Files
B2BCall-dialer/agente.md
Matheus 2f130622d1 feat: bootstrap b2bcall saas architecture
- monorepo skeleton (apps/, packages/, infrastructure/, scripts/, docs/)
- docker-compose with PostgreSQL 18 and Redis 7 (localhost-only)
- .gitignore and .env.example
- initial TODO.md and docs/ARCHITECTURE.md
2026-08-27 23:12:29 -03:00

6481 lines
58 KiB
Markdown

# AGENTE.md
# B2BCall — SaaS Multi-Tenant de Call Center, Discagem Preditiva, Telefonia, IA e Billing
---
# 1. MISSÃO
Você é o engenheiro principal responsável por projetar, desenvolver, instalar, configurar, testar e colocar em funcionamento uma plataforma SaaS profissional chamada:
# B2BCall
O B2BCall será uma plataforma comercial multi-tenant para:
* telefonia IP;
* PBX;
* Call Center;
* ACD;
* filas;
* agentes;
* ramais;
* troncos SIP;
* dialplan;
* discagem automática;
* discagem preditiva;
* campanhas;
* importação de leads;
* gravação de chamadas;
* transcrição de chamadas;
* inteligência artificial para análise de chamadas;
* score de qualidade;
* monitoramento em tempo real;
* relatórios;
* medição de consumo;
* tarifação;
* billing;
* fechamento mensal por tenant.
Este projeto NÃO é:
* uma prova de conceito;
* somente frontend;
* somente backend;
* somente FreeSWITCH;
* um mockup;
* um painel simples de PBX;
* um clone de FreePBX;
* um protótipo descartável.
O resultado esperado é uma base sólida para um produto SaaS comercial.
---
# 2. FORMA DE EXECUÇÃO
Este projeto deverá utilizar o sistema NORMAL de permissões do Claude Code.
NÃO tente:
* desativar o sistema de permissões;
* contornar confirmações;
* alterar configurações do Claude Code para reduzir segurança;
* criar mecanismos externos para evitar autorização.
Dentro das operações permitidas pelo Claude Code, trabalhe de forma autônoma.
Não pare para perguntar decisões técnicas triviais.
Quando houver várias alternativas tecnicamente válidas:
1. analise;
2. escolha a melhor;
3. implemente;
4. documente;
5. teste;
6. continue.
---
# 3. ESCOPO DE SEGURANÇA
A autorização deste projeto vale SOMENTE para o servidor local onde este arquivo `agente.md` está localizado.
Mesmo que o processo esteja rodando como:
```text
root
```
isso NÃO representa autorização para administrar outros servidores.
Regra obrigatória:
```text
root neste servidor
!=
administrador da rede
```
---
# 4. PROIBIDO ACESSAR OUTROS SERVIDORES
Não acessar automaticamente outros servidores, equipamentos ou dispositivos.
É proibido utilizar:
```text
ssh
scp
sftp
rsync remoto
ansible
pssh
fabric
salt
```
contra outros hosts.
Não acessar automaticamente:
* OpenSIPS existentes;
* FreeSWITCH existentes;
* Asterisk existentes;
* bancos externos;
* MikroTik;
* switches;
* roteadores;
* hypervisors;
* NAS;
* storage;
* servidores de produção;
* Kubernetes;
* Docker remoto;
* SBCs;
* carriers.
Somente integrar outro equipamento quando o usuário fornecer explicitamente os dados necessários.
---
# 5. PROIBIDO DESCOBRIR A REDE
Não executar:
```text
nmap
masscan
arp-scan
netdiscover
```
ou ferramenta equivalente para descobrir infraestrutura.
Não realizar sweeps em:
```text
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
```
Não utilizar `known_hosts`, SSH config ou histórico para descobrir servidores.
---
# 6. NÃO PROCURAR CREDENCIAIS DE OUTROS SISTEMAS
Não procurar deliberadamente credenciais em:
```text
/root/.ssh
/home/*/.ssh
shell history
browser profiles
password managers
cloud credentials
VPN credentials
Ansible inventories
Kubernetes configs
```
Se encontrar incidentalmente referência de outro ambiente:
IGNORE.
Não testar.
Não conectar.
Não copiar.
---
# 7. DIAGNÓSTICO INICIAL
Comece executando:
```bash
pwd
ls -lah
cat /etc/os-release
uname -a
ip addr
ip route
df -h
lsblk
free -h
nproc
```
Esses comandos servem apenas para entender o servidor local.
A existência de uma rota não representa autorização para explorar essa rede.
---
# 8. AMBIENTE
Servidor esperado:
```text
Debian 13
```
O servidor pode estar inicialmente limpo.
Instale e configure os componentes necessários conforme as permissões concedidas pelo Claude Code.
---
# 9. DIRETÓRIO DO PROJETO
O diretório contendo:
```text
agente.md
```
deverá ser considerado a raiz inicial do projeto.
Descubra usando:
```bash
pwd
```
Evite espalhar arquivos do projeto fora dessa estrutura sem necessidade.
---
# 10. LOGO
Existe no diretório do projeto:
```text
b2blogo.png
```
Esta é a identidade visual oficial do B2BCall.
Não sobrescrever.
Não alterar o original.
Copiar para o frontend, por exemplo:
```text
apps/frontend/public/branding/b2blogo.png
```
Usar em:
* login;
* sidebar;
* loading;
* favicon derivado;
* relatórios;
* páginas institucionais do sistema.
---
# 11. FREESWITCH PAT
Existe uma credencial privada para download/build do FreeSWITCH.
Ela deverá estar disponível como:
```text
FREESWITCH_PAT
```
Verifique somente a presença:
```bash
test -n "$FREESWITCH_PAT"
```
NUNCA execute:
```bash
echo "$FREESWITCH_PAT"
```
Nunca salvar a credencial em:
* Git;
* README;
* documentação;
* Dockerfile;
* docker-compose.yml;
* banco;
* logs;
* `.env.example`;
* source code.
Preferir Docker BuildKit Secret.
A credencial deverá existir somente durante download/build.
Ela não deverá permanecer na imagem runtime.
---
# 12. STACK
Utilizar preferencialmente:
## Backend
```text
Node.js
TypeScript
NestJS
Fastify
```
## Frontend
```text
Next.js
React
TypeScript
Tailwind CSS
shadcn/ui
TanStack Query
TanStack Table
Recharts
Lucide Icons
```
## Banco
```text
PostgreSQL
```
## Cache / Jobs
```text
Redis
BullMQ
```
## Telefonia
```text
FreeSWITCH
```
## Reverse Proxy
```text
nginx
```
---
# 13. ARQUITETURA MONOREPO
Estrutura sugerida:
```text
apps/
frontend/
api/
dialer-worker/
freeswitch-events/
freeswitch-config/
scheduler/
ai-worker/
billing-worker/
packages/
database/
auth/
billing/
ai/
telephony/
shared/
types/
ui/
infrastructure/
docker/
freeswitch/
postgres/
redis/
nginx/
scripts/
docs/
```
Pode adaptar se houver justificativa técnica.
---
# 14. SERVIÇOS DOCKER
Criar aproximadamente:
```text
b2bcall-frontend
b2bcall-api
b2bcall-dialer
b2bcall-fs-events
b2bcall-fs-config
b2bcall-scheduler
b2bcall-ai-worker
b2bcall-billing-worker
b2bcall-freeswitch
b2bcall-postgres
b2bcall-redis
b2bcall-nginx
```
---
# 15. FREESWITCH
Utilizar FreeSWITCH como núcleo de telefonia.
Módulos importantes:
```text
mod_sofia
mod_event_socket
mod_callcenter
mod_xml_curl
mod_odbc_cdr
mod_commands
mod_dptools
mod_local_stream
mod_avmd
mod_curl
```
Carregar somente o necessário.
---
# 16. PRINCÍPIO FUNDAMENTAL DE TELEFONIA
Não recriar dentro de Node.js funcionalidades que o FreeSWITCH já possui.
Separação:
```text
B2BCall Predictive Engine
=
decide quantas chamadas iniciar
FreeSWITCH mod_callcenter
=
decide para qual agente entregar chamadas atendidas
```
---
# 17. TOPOLOGIA SIP
Arquitetura esperada:
```text
Internet
|
OpenSIPS
|
Rede SIP privada
|
FreeSWITCH
```
O FreeSWITCH NÃO deverá depender de IP SIP público.
Troncos poderão estar em rede privada:
```text
FreeSWITCH
|
Rede privada
|
Carrier / SBC
```
---
# 18. RTP
Separar claramente:
```text
SIP signaling
```
de:
```text
RTP media
```
Preparar arquitetura compatível com:
```text
OpenSIPS + RTPengine
```
quando necessário.
Não assumir que OpenSIPS manipula RTP.
---
# 19. CONTAINER FREESWITCH
Criar imagem própria/controlada pelo projeto.
Não depender cegamente de imagem pública abandonada.
Avaliar:
```text
network_mode: host
```
ou:
```text
macvlan / ipvlan
```
considerando SIP e grande range UDP de RTP.
Documentar decisão em:
```text
docs/NETWORK_ARCHITECTURE.md
```
---
# 20. SOFIA PROFILES
Criar separação lógica como:
```text
internal
opensips
carriers
```
quando adequado.
Configurações:
* IP;
* porta;
* transport;
* codecs;
* context;
* ACL;
* NAT;
* timers.
---
# 21. MOD_EVENT_SOCKET
Utilizar:
```text
mod_event_socket
```
como principal integração de controle.
Criar serviço:
```text
b2bcall-fs-events
```
Manter conexão ESL permanente.
Não executar `fs_cli` via shell para cada ação operacional.
---
# 22. EVENT SOCKET SECURITY
Porta padrão:
```text
8021
```
NÃO pública.
Criar:
* password forte;
* ACL;
* firewall;
* acesso somente pela aplicação autorizada.
Nunca usar senha padrão.
---
# 23. EVENTOS FREESWITCH
Consumir no mínimo:
```text
HEARTBEAT
CHANNEL_CREATE
CHANNEL_ORIGINATE
CHANNEL_PROGRESS
CHANNEL_PROGRESS_MEDIA
CHANNEL_ANSWER
CHANNEL_BRIDGE
CHANNEL_UNBRIDGE
CHANNEL_HANGUP
CHANNEL_HANGUP_COMPLETE
CHANNEL_DESTROY
CHANNEL_STATE
CHANNEL_CALLSTATE
BACKGROUND_JOB
```
CUSTOM relevantes:
```text
callcenter::info
sofia::register
sofia::unregister
sofia::expire
sofia::gateway_state
```
Para AVMD:
```text
avmd::start
avmd::beep
avmd::stop
```
---
# 24. NORMALIZAÇÃO DOS EVENTOS
Criar eventos internos B2BCall.
Exemplo:
```text
CALL_CREATED
CALL_RINGING
CALL_ANSWERED
CALL_BRIDGED
CALL_ENDED
EXTENSION_REGISTERED
EXTENSION_UNREGISTERED
AGENT_STATUS_CHANGED
GATEWAY_UP
GATEWAY_DOWN
```
Não espalhar headers ESL pelo domínio inteiro.
---
# 25. TELEPHONY PROVIDER
Criar interface:
```typescript
interface TelephonyProvider {
originate(): Promise<void>;
killCall(): Promise<void>;
transfer(): Promise<void>;
bridge(): Promise<void>;
getChannels(): Promise<unknown>;
getCalls(): Promise<unknown>;
getRegistrations(): Promise<unknown>;
getGateways(): Promise<unknown>;
getQueues(): Promise<unknown>;
setAgentStatus(): Promise<void>;
setAgentContact(): Promise<void>;
addAgentToQueue(): Promise<void>;
removeAgentFromQueue(): Promise<void>;
reloadXml(): Promise<void>;
}
```
Implementação:
```text
FreeSwitchTelephonyProvider
```
---
# 26. MOD_XML_CURL
Utilizar principalmente para:
```text
Directory
Dialplan
```
Criar:
```text
b2bcall-fs-config
```
Fluxo:
```text
FreeSWITCH
mod_xml_curl
B2BCall fs-config
PostgreSQL
XML
```
Não colocar todas as configurações críticas via XML Curl.
---
# 27. CONFIGURAÇÕES DE BOOT
Manter localmente quando adequado:
```text
event_socket.conf.xml
modules.conf.xml
sofia bootstrap
xml_curl.conf.xml
switch.conf.xml
```
O FreeSWITCH precisa conseguir subir mesmo se a API estiver temporariamente indisponível.
---
# 28. SAAS MULTI-TENANT DESDE O PRIMEIRO COMMIT
O B2BCall é MULTI-TENANT desde sua arquitetura inicial.
Isso deve existir em:
* banco;
* API;
* autenticação;
* RBAC;
* WebSocket;
* FreeSWITCH;
* ramais;
* agentes;
* filas;
* trunks;
* campanhas;
* chamadas;
* leads;
* gravações;
* IA;
* billing;
* relatórios.
---
# 29. TENANTS
Criar:
```text
tenants
```
Campos:
```text
id UUID
code
slug
legal_name
trade_name
tax_id
status
timezone
locale
billing_currency
telephony_domain
created_at
updated_at
deleted_at
```
Status:
```text
TRIAL
ACTIVE
SUSPENDED
PAST_DUE
CANCELLED
```
---
# 30. TENANT ID
Toda tabela tenant-scoped deverá possuir:
```text
tenant_id UUID NOT NULL
```
Exemplos:
```text
extensions
agents
queues
trunks
campaigns
leads
calls
recordings
ai_jobs
usage_events
```
---
# 31. NÃO CONFIAR NO TENANT_ID DO FRONTEND
Nunca confiar em:
```json
{
"tenant_id": "..."
}
```
enviado pelo browser.
Resolver tenant a partir de:
```text
authenticated user
+
tenant membership
+
authorized tenant context
```
---
# 32. POSTGRESQL RLS
Implementar:
```text
ROW LEVEL SECURITY
```
nas tabelas críticas tenant-scoped.
Defense-in-depth:
```text
RBAC
+
object authorization
+
tenant repositories
+
PostgreSQL RLS
```
---
# 33. TENANT CONTEXT
Criar mecanismo seguro de tenant na conexão/transaction PostgreSQL.
Exemplo conceitual:
```text
app.current_tenant_id
```
Policies deverão utilizar esse contexto.
Platform Super Admin deverá possuir fluxo privilegiado explícito e auditado.
---
# 34. UNIQUENESS
Não utilizar:
```text
UNIQUE(extension_number)
```
globalmente.
Utilizar:
```text
UNIQUE(tenant_id, extension_number)
```
O mesmo vale para:
* agentes;
* filas;
* campanhas;
* trunks;
* pausas;
* dispositions.
---
# 35. TELEPHONY NODES
Mesmo começando com um FreeSWITCH, criar:
```text
telephony_nodes
```
Campos:
```text
id
name
hostname
internal_ip
esl_host
esl_port
instance_id
status
max_sessions
max_cps
enabled
```
---
# 36. TENANT TELEPHONY ASSIGNMENT
Criar:
```text
tenant_telephony_assignments
```
Inicialmente:
```text
tenant
FreeSWITCH principal
```
Arquitetura deve permitir expansão futura.
---
# 37. MOD_CALLCENTER
Utilizar:
```text
mod_callcenter
```
como ACD.
FreeSWITCH controla:
```text
queues
agents
tiers
offering
distribution
bridging
wrap-up
```
B2BCall controla:
```text
users
permissions
campaigns
leads
predictive pacing
billing
AI
reports
audit
```
---
# 38. CALLCENTER DATABASE
Evitar SQLite como banco operacional de produção.
Utilizar PostgreSQL via ODBC quando adequado.
Separar schemas:
```text
app
freeswitch
```
ou solução equivalente.
---
# 39. RAMAIS
Criar tela:
```text
Telefonia → Ramais
```
Tabela:
```text
extensions
```
Campos:
```text
tenant_id
number
name
domain
sip_password
caller_id_name
caller_id_number
context
sofia_profile
codecs
max_registrations
enabled
```
Gerar senha SIP forte.
Criptografar em repouso.
Nunca mostrar novamente a senha inteira.
---
# 40. STATUS DOS RAMAIS
Consumir eventos:
```text
sofia::register
sofia::unregister
sofia::expire
```
Atualizar via WebSocket.
Evitar polling frequente.
---
# 41. TRONCOS
Criar:
```text
Telefonia → Troncos
```
Tabela:
```text
trunks
```
Campos:
```text
tenant_id
name
description
sofia_profile
host
proxy
realm
register
username
password
from_user
from_domain
register_proxy
outbound_proxy
expire_seconds
retry_seconds
caller_id_name
caller_id_number
codecs
dtmf_mode
ping
ping_frequency
transport
inbound_context
max_cps
max_channels
enabled
```
Suportar:
```text
IP Authentication
Registration
Username/Password
```
---
# 42. STATUS DOS TRONCOS
Mostrar estados reais:
```text
UP
DOWN
REGISTERED
TRYING
FAILED
UNREGISTERED
UNKNOWN
```
Consumir:
```text
sofia::gateway_state
```
e comandos seguros quando necessário.
---
# 43. DIALPLAN
Criar:
```text
Telefonia → Dialplan
```
Não fazer somente textarea.
Editor estruturado:
```text
Context
Extension Name
Condition Field
Condition Expression
Actions
Anti-Actions
Continue
Order
Enabled
```
Salvar no PostgreSQL.
Gerar XML.
---
# 44. VERSIONAMENTO DIALPLAN
Criar:
```text
dialplan_versions
```
Fluxo:
1. gerar;
2. validar XML;
3. versionar;
4. ativar;
5. `reloadxml`;
6. verificar;
7. rollback se necessário.
---
# 45. AGENTES
Separar:
```text
User
Agent
Extension
```
Criar:
```text
agents
agent_sessions
agent_state_events
```
Todos tenant-scoped.
---
# 46. ESTADOS DOS AGENTES
Estados canônicos:
```text
OFFLINE
LOGGED_IN
AVAILABLE
RESERVED
RINGING
IN_CALL
WRAP_UP
PAUSED
```
Mapear estados FreeSWITCH corretamente.
---
# 47. LOGIN DO AGENTE
Fluxo:
```text
Login B2BCall
Validar usuário
Validar ramal
Criar agent_session
Configurar agent contact
Configurar mod_callcenter
Configurar tiers
AVAILABLE
```
---
# 48. PAUSAS
Criar:
```text
Call Center → Pausas
```
Tabelas:
```text
pause_reasons
agent_pause_events
```
Campos:
```text
tenant_id
name
code
description
max_duration
paid
enabled
```
Ao pausar:
```text
FreeSWITCH → On Break
B2BCall → PAUSED
```
---
# 49. TELA DO AGENTE
Criar interface específica.
Mostrar:
```text
Agente
Ramal
Fila
Campanha
Status
Tempo no status
Lead
Telefone
Tempo da chamada
```
Botões:
```text
DISPONÍVEL
PAUSA
FINALIZAR PAUSA
LOGOUT
```
---
# 50. FILAS
Criar:
```text
Call Center → Filas
```
Campos relevantes:
```text
tenant_id
name
description
strategy
moh
announce_sound
announce_frequency
max_wait_time
max_wait_time_with_no_agent
agent_no_answer_status
tier_rules
discard_abandoned_after
abandoned_resume_allowed
skip_agents_with_external_calls
recording_enabled
enabled
```
---
# 51. ESTRATÉGIAS
Suportar:
```text
longest-idle-agent
round-robin
top-down
agent-with-least-talk-time
agent-with-fewest-calls
sequentially-by-agent-order
ring-all
ring-progressively
```
Mostrar tooltip explicativo.
---
# 52. TIERS
Criar relação:
```text
Queue
Tier
Agent
```
Campos:
```text
tenant_id
queue_id
agent_id
level
position
```
---
# 53. WRAP-UP
Utilizar:
```text
wrap-up-time
```
Enquanto em wrap-up:
```text
agente não está disponível
```
O Predictive Dialer deve considerar isso.
---
# 54. MONITORAMENTO DAS FILAS
Criar:
```text
Monitoramento → Filas
```
Mostrar em tempo real:
```text
Chamadas esperando
Agentes logados
Disponíveis
Reservados
Ringing
Em chamada
Wrap-up
Pausados
Offline
Maior espera
TME
TMA
Atendidas
Abandonadas
Service Level
Abandon Rate
```
---
# 55. MONITORAMENTO DOS RAMAIS
Criar:
```text
Monitoramento → Ramais
```
Cada ramal deverá aparecer em card.
Convenção obrigatória:
```text
CINZA
offline
VERDE
disponível
LARANJA
ocupado
AZUL
agente logado
VERMELHO
agente em pausa
```
Prioridade:
```text
PAUSA
>
EM CHAMADA
>
AGENTE LOGADO
>
DISPONÍVEL
>
OFFLINE
```
Mostrar:
```text
Ramal
Nome
Agente
Fila
Status
Tempo no estado
Campanha
Duração da chamada
```
---
# 56. QUOTAS SAAS
Criar sistema genérico de:
```text
entitlements
```
Não espalhar regras:
```text
if plan == PRO
```
pelo código.
Entitlements:
```text
max_extensions
max_agents
max_trunks
max_queues
max_campaigns
max_cps
max_concurrent_calls
max_daily_calls
max_monthly_calls
max_recording_storage_gb
recording_enabled
ai_enabled
ai_transcription_enabled
ai_analysis_enabled
api_access_enabled
```
---
# 57. QUOTA DE RAMAIS
Antes de criar:
```text
active_extensions < max_extensions
```
Caso ultrapasse:
retornar erro de quota.
---
# 58. QUOTA DE AGENTES
Antes de criar agente:
```text
active_agents < max_agents
```
---
# 59. QUOTA DE TRONCOS
Antes de criar trunk:
```text
active_trunks < max_trunks
```
---
# 60. CPS TENANT
Cada tenant possui:
```text
max_cps
```
Esse limite deve considerar a soma de todas as campanhas do tenant.
---
# 61. CHAMADAS SIMULTÂNEAS TENANT
Cada tenant possui:
```text
max_concurrent_calls
```
Mesmo que tenha várias campanhas, o total não pode ultrapassar.
---
# 62. HIERARQUIA DE LIMITES
Toda originação deve respeitar:
```text
GLOBAL
TELEPHONY NODE
TENANT
TRUNK
CAMPAIGN
```
CPS efetivo:
```text
MIN(
global_available_cps,
node_available_cps,
tenant_available_cps,
trunk_available_cps,
campaign_available_cps
)
```
---
# 63. CAMPANHAS
Criar:
```text
Discador → Campanhas
```
Campos:
```text
tenant_id
name
description
queue_id
trunk_id
caller_id_name
caller_id_number
timezone
start_date
end_date
days_of_week
start_time
end_time
max_cps
max_concurrent_calls
pacing_initial
pacing_min
pacing_max
target_abandon_rate
ring_timeout
max_attempts
recording_enabled
avmd_enabled
ai_transcription_enabled
ai_analysis_enabled
```
---
# 64. STATUS CAMPANHAS
```text
DRAFT
READY
WAITING_SCHEDULE
RUNNING
PAUSED
DRAINING
STOPPED
COMPLETED
ERROR
```
---
# 65. DRAINING
Ao selecionar:
```text
DRAIN
```
não originar novas chamadas.
Permitir finalizar as existentes.
---
# 66. STOP
Por padrão:
```text
STOP
=
não originar novas chamadas
+
deixar chamadas já conectadas terminarem
```
Não derrubar chamadas ativas automaticamente.
---
# 67. LEADS
Criar:
```text
leads
```
Campos:
```text
tenant_id
campaign_id
name
phone_original
phone_normalized
status
attempt_count
last_attempt_at
next_attempt_at
last_result
custom_fields JSONB
created_at
updated_at
```
---
# 68. STATUS LEAD
```text
NEW
READY
RESERVED
ORIGINATING
RINGING
ANSWERED
QUEUEING
CONNECTED_AGENT
BUSY
NO_ANSWER
FAILED
VOICEMAIL
CALLBACK
COMPLETED
DO_NOT_CALL
MAX_ATTEMPTS
```
---
# 69. IMPORTAÇÃO CSV
Suportar formato mínimo:
```csv
nome,telefone
Joao Silva,48999999999
Maria Souza,11999999999
```
Wizard:
```text
Upload
Preview
Mapeamento
Validação
Normalização
Duplicados
Importação
```
Mostrar:
```text
Total
Válidos
Inválidos
Duplicados
Importados
```
Processar em streaming/batches.
---
# 70. NORMALIZAÇÃO DE TELEFONE
Criar serviço dedicado.
Não espalhar regexes.
Guardar:
```text
phone_original
phone_normalized
```
Inicialmente preparado para Brasil.
Arquitetura preparada para E.164.
---
# 71. LISTA DE BLOQUEIO
Criar:
```text
Discador → Lista de Bloqueio
```
Tabela:
```text
suppression_list
```
Tenant-scoped.
Antes de qualquer chamada:
```text
CHECK SUPPRESSION LIST
```
obrigatório.
---
# 72. PREDICTIVE DIALER
Criar serviço:
```text
PredictiveDialerEngine
```
Não implementar apenas:
```text
for lead -> originate
```
Isso não é discador preditivo.
---
# 73. DADOS DO PREDICTIVE ENGINE
Considerar:
```text
available_agents
reserved_agents
ringing_agents
agents_in_call
agents_in_wrapup
agents_paused
calls_originating
calls_ringing
answered_waiting_agent
answer_probability
average_answer_delay
average_talk_time
abandon_rate
current_cps
max_cps
max_concurrent_calls
```
---
# 74. PREVISÃO DE LIBERAÇÃO
Utilizar:
```text
elapsed_talk_time
+
historical talk time distribution
```
para estimar agentes disponíveis em:
```text
5 segundos
10 segundos
15 segundos
20 segundos
```
Não precisa Machine Learning inicialmente.
Preferir algoritmo estatístico determinístico e explicável.
---
# 75. EWMA
Utilizar EWMA ou equivalente para:
```text
answer_probability
average_answer_delay
TMA
abandon_rate
```
Evitar oscilações violentas do pacing.
---
# 76. CÁLCULO CONCEITUAL
```text
expected_agent_capacity =
available_agents
+
predicted_agents_becoming_available
```
```text
expected_answers =
calls_to_originate * answer_probability
```
Objetivo:
```text
expected_answers
expected_agent_capacity
```
Aplicando:
```text
pacing_factor
```
e limites.
---
# 77. CPS DISTRIBUÍDO
Implementar token bucket ou equivalente.
Utilizar Redis.
Deve funcionar com múltiplos workers.
Não utilizar somente:
```text
sleep()
```
como controle.
---
# 78. RESERVA DE LEADS
Evitar duplicidade.
Utilizar PostgreSQL:
```sql
FOR UPDATE SKIP LOCKED
```
ou solução transacional equivalente.
Fluxo:
```text
READY
RESERVED
ORIGINATING
```
atômico.
---
# 79. LOCK DE CAMPANHA
Criar:
```text
dialer:campaign:{id}
```
com:
```text
TTL
ownership token
renewal
safe release
```
---
# 80. ORIGINATE
Utilizar:
```text
bgapi originate
```
via ESL.
Não originar milhares de chamadas sincronamente.
---
# 81. IDENTIFICADORES DA CHAMADA
Criar antes do originate:
```text
tenant_id
call_id
attempt_id
campaign_id
lead_id
origination_uuid
```
Enviar como channel variables:
```text
b2bcall_tenant_id
b2bcall_call_id
b2bcall_attempt_id
b2bcall_campaign_id
b2bcall_lead_id
```
---
# 82. STATE MACHINE
```text
CREATED
RESERVED
ORIGINATING
ORIGINATED
RINGING
ANSWERED
QUEUEING
AGENT_CONNECTED
COMPLETED
BUSY
NO_ANSWER
FAILED
ABANDONED
```
Persistir transições.
---
# 83. FLUXO DA CHAMADA PREDITIVA
```text
Lead
Reserve
Predictive Engine
CPS Limiter
FreeSWITCH bgapi originate
Sofia Gateway
PSTN
```
Se atender:
```text
ANSWER
AVMD opcional
mod_callcenter
Queue
Agent
Bridge
```
---
# 84. ABANDONO
Se:
```text
abandon_rate > target
```
reduzir pacing.
Se continuar:
```text
modo conservador
```
Se atingir limite crítico:
```text
suspender temporariamente novas originations
```
---
# 85. NÃO DISCAGEM SEM CAPACIDADE
Não utilizar o sistema simplesmente para descobrir quais números atendem.
O objetivo é conectar clientes a agentes.
Não originar agressivamente sem capacidade prevista de agentes.
---
# 86. RETRY
Criar regras configuráveis.
Exemplo:
```text
BUSY -> 15 min
NO_ANSWER -> 60 min
CONGESTION -> 5 min
FAILED -> 30 min
```
Nunca retry infinito.
---
# 87. AVMD
Utilizar opcionalmente:
```text
mod_avmd
```
Não tratar como detector perfeito de humano/máquina.
Resultados internos quando possível:
```text
HUMAN
MACHINE_BEEP
UNKNOWN
```
---
# 88. CALLBACK
Criar:
```text
callbacks
```
Campos:
```text
tenant_id
lead_id
campaign_id
agent_id
scheduled_at
timezone
preferred_agent
notes
status
```
Scheduler deverá reativar corretamente.
---
# 89. DISPOSIÇÕES
Criar:
```text
Call Center → Disposições
```
Exemplos:
```text
VENDA
SEM INTERESSE
CALLBACK
NÚMERO ERRADO
DO_NOT_CALL
CAIXA POSTAL
OUTRO
```
Permitir personalização por tenant.
---
# 90. GRAVAÇÃO
Criar módulo profissional de gravações.
Tabela:
```text
recordings
```
Campos:
```text
tenant_id
call_id
storage_provider
object_key
format
duration_seconds
channels
size_bytes
checksum
recorded_at
retention_until
status
```
---
# 91. FREESWITCH RECORDING
Utilizar:
```text
record_session
```
ou mecanismo apropriado.
Preferencialmente gravar chamadas de Call Center em estéreo quando tecnicamente adequado:
```text
RECORD_STEREO=true
```
Objetivo:
```text
canal A
canal B
```
permitindo melhor identificação de agente e cliente.
Validar corretamente qual direção corresponde a qual speaker.
---
# 92. OBJECT STORAGE
Criar abstração:
```text
ObjectStorageProvider
```
Suportar:
```text
Local
S3 Compatible
```
Preparar para:
```text
AWS S3
MinIO
```
---
# 93. STORAGE PATH
Usar estrutura segura, por exemplo:
```text
tenants/{tenant_id}/recordings/YYYY/MM/DD/{call_id}.wav
```
Tenant nunca poderá fornecer object key arbitrário de outro tenant.
---
# 94. RETENÇÃO
Configurações:
```text
recording_retention_days
transcription_retention_days
```
por tenant/plano.
Scheduler deverá aplicar retenção.
---
# 95. INTELIGÊNCIA ARTIFICIAL
Criar módulo:
```text
IA
```
Submenus:
```text
Providers
Modelos
Prompts
Scorecards
Análises
Uso
Configurações
```
---
# 96. AI PROVIDER ABSTRACTION
Não hardcode OpenAI no domínio.
Criar abstração:
```typescript
interface AIProvider {
getCapabilities(): Promise<unknown>;
validateCredentials(): Promise<boolean>;
transcribe?(): Promise<unknown>;
analyze?(): Promise<unknown>;
summarize?(): Promise<unknown>;
structuredGenerate?(): Promise<unknown>;
}
```
---
# 97. PROVIDERS INICIAIS
Preparar adapters para:
```text
OpenAI
Anthropic
```
Arquitetura deve permitir:
```text
Google
Azure OpenAI
AWS Bedrock
modelos locais
outros providers
```
futuramente.
---
# 98. NOMENCLATURA
Na integração utilizar:
```text
OpenAI API
```
e:
```text
Anthropic API
```
Não amarrar o domínio ao produto:
```text
ChatGPT
```
---
# 99. AI PROVIDERS TABLE
Criar:
```text
ai_providers
```
Campos:
```text
id
scope
tenant_id nullable
provider_type
name
base_url optional
encrypted_api_key
organization optional
project optional
enabled
created_at
updated_at
```
---
# 100. PROVIDER GLOBAL E BYOK
Permitir:
## Provider global
Configurado pelo platform admin.
## BYOK
```text
Bring Your Own Key
```
Tenant cadastra sua própria API key.
---
# 101. API KEYS
Criptografar em repouso usando:
```text
AES-256-GCM
```
ou equivalente moderno.
Master key fora do PostgreSQL.
Nunca mostrar key inteira após salvar.
---
# 102. CAPABILITIES
Criar conceito:
```text
TRANSCRIPTION
DIARIZATION
TEXT_ANALYSIS
STRUCTURED_OUTPUT
EMBEDDINGS
REALTIME_AUDIO
```
Nem todo provider terá todas as capacidades.
---
# 103. AI MODELS
Criar:
```text
ai_models
```
Campos:
```text
provider_id
external_model_id
display_name
capabilities
input_cost
output_cost
audio_cost
enabled
```
Modelos devem ser configuráveis.
---
# 104. TRANSCRIPTION PROVIDER
Separar interface:
```text
TranscriptionProvider
```
Configuração:
```text
provider
model
language
diarization
```
---
# 105. ANALYSIS PROVIDER
Separar de transcrição.
Permitir exemplo:
```text
OpenAI → Transcrição
Anthropic → Análise
```
ou:
```text
OpenAI → Transcrição
OpenAI → Análise
```
---
# 106. PIPELINE IA
Após hangup:
```text
CALL COMPLETED
Finalize Recording
Upload Object Storage
Create AI Job
Transcription
Speaker Mapping
Analysis
Structured Results
Usage Metering
```
Tudo assíncrono.
Nunca bloquear a chamada esperando IA.
---
# 107. AI JOBS
Criar:
```text
ai_jobs
```
Tipos:
```text
TRANSCRIPTION
ANALYSIS
REANALYSIS
```
Status:
```text
PENDING
PROCESSING
COMPLETED
FAILED
RETRYING
CANCELLED
```
---
# 108. RETRY IA
Implementar:
```text
retry
exponential backoff
dead-letter strategy
```
Limitar tentativas.
---
# 109. TRANSCRIÇÕES
Criar:
```text
call_transcriptions
```
Campos:
```text
tenant_id
call_id
provider_id
model
language
text
status
duration_seconds
provider_request_id
input_usage
output_usage
provider_cost
created_at
```
---
# 110. SEGMENTOS
Criar:
```text
call_transcript_segments
```
Campos:
```text
transcription_id
speaker
start_ms
end_ms
text
confidence optional
```
Speaker:
```text
AGENT
CUSTOMER
UNKNOWN
```
---
# 111. SPEAKER MAPPING
Sempre que possível utilizar canais estéreo para identificar:
```text
Agent
Customer
```
Diarização pode ser apoio.
Não confiar cegamente em classificação probabilística quando direção de áudio permite identificação melhor.
---
# 112. ANÁLISE DA CHAMADA
Criar:
```text
call_ai_analyses
```
Resultado estruturado:
```text
summary
customer_intent
outcome
sentiment
topics
keywords
objections
questions
action_items
compliance_flags
quality_score
agent_score
customer_sentiment_score
risk_flags
sales_opportunity
next_best_action
```
---
# 113. OUTPUT ESTRUTURADO
Não usar somente texto livre.
Utilizar schemas.
Exemplo:
```json
{
"summary": "...",
"sentiment": "NEUTRAL",
"topics": [],
"objections": [],
"quality_score": 82,
"compliance_flags": [],
"action_items": []
}
```
Validar antes de persistir.
---
# 114. PROMPTS
Criar:
```text
ai_prompt_templates
ai_prompt_versions
```
Prompts não devem ficar hardcoded.
---
# 115. PROMPT POR TENANT
Tenant poderá definir prompt próprio.
Exemplo:
```text
analise esta chamada como atendimento de suporte
```
---
# 116. PROMPT POR CAMPANHA
Campanha poderá sobrescrever.
Exemplo cobrança:
```text
promessa de pagamento
data prometida
objeções
```
Exemplo vendas:
```text
interesse
produto
objeções
intenção de compra
```
---
# 117. SCORECARD
Criar:
```text
quality_scorecards
quality_scorecard_items
quality_evaluations
```
Itens:
```text
Saudação
Identificação
Empatia
Entendimento
Apresentação
Objeções
Encerramento
Compliance
```
Campos:
```text
weight
description
evaluation_prompt
```
---
# 118. QA AUTOMÁTICO
Gerar:
```text
score 0-100
```
por chamada.
Guardar:
```text
score
criterion_scores
summary_justification
```
Não armazenar chain-of-thought do modelo.
---
# 119. DASHBOARD IA
Mostrar:
```text
Chamadas analisadas
Score médio
Sentimento
Principais assuntos
Principais objeções
Compliance alerts
Agentes com maior score
Agentes com menor score
```
---
# 120. DETALHE DA CHAMADA
Criar abas:
```text
Resumo
Timeline
Gravação
Transcrição
Análise IA
Eventos
Billing
```
---
# 121. PLAYER DE ÁUDIO
Implementar:
```text
play
pause
timeline
duration
```
Se possível sincronizar transcrição.
---
# 122. PRIVACIDADE IA
Permitir:
```text
AI OFF
TRANSCRIPTION ONLY
TRANSCRIPTION + ANALYSIS
```
por:
* tenant;
* campanha;
* fila.
---
# 123. REDACTION
Criar abstração:
```text
SensitiveDataRedactor
```
Preparar para mascarar:
```text
CPF
CNPJ
telefone
email
cartão
outros dados
```
antes de enviar ao provider quando política exigir.
---
# 124. AI USAGE METERING
Gerar usage:
```text
AI_TRANSCRIPTION_SECONDS
AI_ANALYSIS_REQUEST
AI_INPUT_TOKENS
AI_OUTPUT_TOKENS
```
---
# 125. BILLING SAAS
Criar billing desde o início.
Não tratar cobrança como relatório calculado posteriormente de maneira improvisada.
---
# 126. PLANOS
Criar:
```text
plans
plan_versions
```
Exemplo:
```text
Starter
Professional
Enterprise
```
Preços e limites devem ser versionados.
---
# 127. SUBSCRIPTIONS
Criar:
```text
tenant_subscriptions
```
Campos:
```text
tenant_id
plan_version_id
status
started_at
ends_at
billing_cycle_anchor
currency
```
---
# 128. PRICE BOOKS
Criar:
```text
price_books
price_book_items
```
Tipos de preço:
```text
BASE_SUBSCRIPTION
EXTENSION_MONTH
AGENT_MONTH
TRUNK_MONTH
CALL
CALL_MINUTE
FIXED_MINUTE
MOBILE_MINUTE
INTERNATIONAL_MINUTE
AI_TRANSCRIPTION_MINUTE
AI_ANALYSIS_CALL
AI_INPUT_TOKEN
AI_OUTPUT_TOKEN
RECORDING_GB_MONTH
```
---
# 129. RATE DECKS
Criar:
```text
rate_decks
rate_deck_entries
```
Campos:
```text
prefix
destination_name
destination_type
price_per_minute
billing_increment_seconds
minimum_seconds
connection_fee
valid_from
valid_until
```
Implementar longest prefix matching.
---
# 130. RATING ENGINE
Criar:
```text
RatingEngine
```
Responsável por:
```text
uso bruto
regra de preço
valor financeiro
```
Nunca calcular billing no frontend.
---
# 131. USAGE LEDGER
Criar tabela imutável:
```text
usage_events
```
Campos:
```text
id UUID
tenant_id
meter
quantity
unit
source_type
source_id
occurred_at
metadata
created_at
```
Exemplos:
```text
CALL_COUNT
CALL_SECONDS
EXTENSION_ACTIVE_DAY
AGENT_ACTIVE_DAY
TRUNK_ACTIVE_DAY
AI_TRANSCRIPTION_SECONDS
AI_ANALYSIS_REQUEST
AI_INPUT_TOKENS
AI_OUTPUT_TOKENS
RECORDING_BYTES
```
---
# 132. RATED USAGE
Criar:
```text
rated_usage_items
```
Campos:
```text
tenant_id
usage_event_id
price_book_item_id
quantity
unit_price
amount
currency
pricing_version
```
---
# 133. CHAMADA FATURÁVEL
Guardar:
```text
billable_seconds
billing_increment
rated_minutes
destination_rate
rated_amount
```
---
# 134. BILLING PERIOD
Criar:
```text
billing_periods
```
Status:
```text
OPEN
CALCULATING
READY
CLOSED
REOPENED
```
---
# 135. MONTHLY STATEMENTS
Criar:
```text
billing_statements
billing_statement_items
```
Relatório mensal por tenant:
```text
Plano
Valor base
Ramais
Quantidade
Valor
Agentes
Quantidade
Valor
Troncos
Quantidade
Valor
Chamadas
Quantidade
Minutos
Quantidade
Valor
Transcrição IA
Quantidade
Valor
Análise IA
Quantidade
Valor
Tokens
Valor
Storage
Valor
Subtotal
Ajustes
Total
```
---
# 136. STATEMENT NÃO É NOTA FISCAL
O sistema deverá chamar isso de:
```text
Usage Statement
Billing Statement
Relatório de Consumo
```
Não afirmar automaticamente que se trata de:
```text
NFCom
NFS-e
Nota Fiscal
```
Integração fiscal é outro módulo.
---
# 137. FECHAMENTO IMUTÁVEL
Depois de:
```text
CLOSED
```
não recalcular silenciosamente.
Para corrigir:
```text
REOPEN
```
com:
```text
user
reason
audit
```
---
# 138. ESTIMATIVA DO MÊS
Tenant Dashboard deverá mostrar:
```text
Valor estimado do mês
```
Mas deixar claro que é valor em aberto.
---
# 139. DASHBOARD DE QUOTAS
Mostrar:
```text
Ramais
8 / 10
Agentes
15 / 20
Troncos
2 / 3
CPS
6 / 10
Chamadas simultâneas
18 / 25
```
---
# 140. PLATFORM SUPER ADMIN
Criar:
```text
platform_super_admin
```
Pode:
```text
criar tenant
suspender tenant
alterar plano
definir quota
definir preços
acessar consumo
executar fechamento
administrar FreeSWITCH
administrar AI providers globais
```
---
# 141. TENANT ADMIN
Criar:
```text
tenant_admin
```
Pode administrar somente seu tenant.
---
# 142. ROLES
Roles iniciais:
```text
platform_super_admin
tenant_admin
supervisor
agent
```
Mas utilizar RBAC configurável.
---
# 143. RBAC
Criar:
```text
roles
permissions
user_roles
role_permissions
```
Permitir roles customizadas.
---
# 144. ROLE SCOPE
Role possui:
```text
PLATFORM
```
ou:
```text
TENANT
```
Nunca permitir escopo global acidental.
---
# 145. PERMISSÕES
Criar permissões como:
```text
tenants.view
tenants.manage
billing.view
billing.manage
pricing.manage
dashboard.view
extensions.view
extensions.manage
trunks.view
trunks.manage
agents.view
agents.manage
queues.view
queues.manage
campaigns.view
campaigns.create
campaigns.update
campaigns.start
campaigns.pause
campaigns.stop
monitoring.view
reports.view
reports.export
recordings.view
recordings.download
ai.view
ai.manage
ai.analyze
freeswitch.view
freeswitch.configure
users.manage
roles.manage
audit.view
```
---
# 146. OBJECT-LEVEL AUTHORIZATION
Permissão:
```text
campaigns.view
```
não é suficiente.
Também verificar:
```text
campaign.tenant_id == user.tenant_id
```
---
# 147. PROTEÇÃO IDOR
Um usuário tenant A tentando:
```text
/api/calls/{uuid-tenant-b}
```
deve receber:
```text
403
```
ou:
```text
404
```
Nunca retornar dados.
---
# 148. AUTENTICAÇÃO
Login:
```text
email
senha
```
Hash:
```text
Argon2id
```
Implementar:
```text
access token
refresh token
refresh rotation
logout
session revocation
password reset
forced password change
```
---
# 149. RATE LIMIT
Login:
```text
5 tentativas/minuto/IP
```
ou estratégia segura equivalente.
Também:
```text
rate per user
progressive blocking
audit
```
---
# 150. AUDIT LOG
Criar:
```text
audit_logs
```
Campos:
```text
tenant_id nullable
user_id
action
entity_type
entity_id
before
after
ip_address
user_agent
created_at
```
Nunca salvar secrets.
---
# 151. EVENTOS DE AUDITORIA
Registrar:
```text
LOGIN
LOGIN_FAILED
TENANT_CREATE
TENANT_SUSPEND
PLAN_CHANGE
QUOTA_CHANGE
PRICE_CHANGE
BILLING_CLOSE
BILLING_REOPEN
USER_CREATE
ROLE_CHANGE
TRUNK_CREATE
EXTENSION_CREATE
AGENT_LOGIN
AGENT_PAUSE
CAMPAIGN_START
CAMPAIGN_PAUSE
CAMPAIGN_STOP
AI_PROVIDER_CHANGE
AI_ENABLED
FREESWITCH_CONFIG_CHANGE
RELOAD
```
---
# 152. MOD_ODBC_CDR
Utilizar preferencialmente:
```text
mod_odbc_cdr
```
com PostgreSQL via ODBC.
Configurar fallback/spool para evitar perda silenciosa de CDR.
---
# 153. MODELO DE CHAMADAS
Criar:
```text
calls
call_legs
call_events
dial_attempts
```
---
# 154. FIELDS CALL
```text
tenant_id
call_id
attempt_id
freeswitch_uuid
sip_call_id
direction
campaign_id
lead_id
queue_id
agent_id
extension_id
trunk_id
caller
called
created_at
progress_at
answer_at
queue_enter_at
agent_answer_at
bridge_at
end_at
ring_time
wait_time
talk_time
duration_seconds
billable_seconds
hangup_cause
disposition
```
---
# 155. TME
Calcular para chamadas atendidas:
```text
agent_answer_at - queue_enter_at
```
Separar tempo médio até abandono.
---
# 156. TMA
Principal:
```text
SUM(talk_time) / answered_calls
```
Permitir indicador separado:
```text
Talk Time + Wrap-Up
```
---
# 157. RELATÓRIO DE CHAMADAS
Filtros:
```text
data
ramal
agente
fila
campanha
trunk
telefone
hangup cause
disposition
```
Platform admin poderá filtrar tenant.
Tenant normal não poderá escolher outro tenant.
---
# 158. RELATÓRIO AGENTES
Mostrar:
```text
Tempo logado
Tempo disponível
Tempo reservado
Tempo ringing
Tempo em chamada
Tempo wrap-up
Tempo pausado
Chamadas atendidas
TMA
```
---
# 159. RELATÓRIO FILAS
Mostrar:
```text
Recebidas
Atendidas
Abandonadas
TME
TMA
Service Level
Abandon Rate
```
---
# 160. RELATÓRIO CAMPANHA
Mostrar:
```text
Leads
Attempts
Answered
Agent Connected
Busy
No Answer
Failed
Callbacks
Answer Rate
Contact Rate
Abandon Rate
TME
TMA
Valor Telefonia
Valor IA
```
---
# 161. WEBSOCKET MULTI-TENANT
Eventos WebSocket devem ser tenant-scoped no servidor.
Não transmitir tudo e filtrar somente no browser.
---
# 162. DASHBOARD TENANT
Mostrar:
```text
Chamadas hoje
Atendidas
Em andamento
Esperando agente
Agentes disponíveis
Agentes ocupados
Agentes pausados
TME
TMA
Answer Rate
Abandon Rate
```
Também:
```text
Consumo do plano
Valor estimado no mês
```
---
# 163. DASHBOARD PLATFORM
Mostrar:
```text
Tenants ativos
Ramais totais
Agentes totais
Chamadas atuais
Chamadas hoje
FreeSWITCH nodes
CPS global
Consumo mensal
Receita estimada
Uso IA
Storage
```
---
# 164. INTERFACE
Este requisito é muito importante.
O B2BCall deverá parecer um produto SaaS moderno e profissional.
Não deve parecer:
```text
FreePBX
FusionPBX
painel Linux
Bootstrap antigo
sistema legado
```
---
# 165. DESIGN SYSTEM
Criar tokens para:
```text
colors
typography
spacing
border radius
shadows
status colors
buttons
forms
badges
cards
tables
dialogs
charts
```
---
# 166. LAYOUT
Criar:
```text
Sidebar
+
Topbar
+
Content
```
Sidebar recolhível.
---
# 167. LOGIN
Utilizar `b2blogo.png`.
Criar tela moderna.
Desktop poderá usar:
```text
Brand B2BCall
|
Login Form
```
Responsiva.
---
# 168. MENU PLATFORM
```text
Visão Geral
Clientes
├─ Tenants
├─ Planos
├─ Assinaturas
└─ Quotas
Billing
├─ Consumo
├─ Tarifas
├─ Fechamentos
└─ Relatórios
Infraestrutura
├─ FreeSWITCH
├─ SIP Profiles
├─ Nodes
└─ Saúde
IA
├─ Providers
├─ Modelos
├─ Uso
└─ Custos
Sistema
├─ Usuários
├─ Permissões
├─ Auditoria
└─ Configurações
```
---
# 169. MENU TENANT
```text
Dashboard
Discador
├─ Campanhas
├─ Leads
├─ Importações
├─ Callbacks
└─ Lista de Bloqueio
Call Center
├─ Agentes
├─ Filas
├─ Pausas
└─ Disposições
Telefonia
├─ Ramais
├─ Troncos
└─ Dialplan
Monitoramento
├─ Campanhas
├─ Filas
├─ Agentes
├─ Ramais
└─ Troncos
Gravações
IA
├─ Análises
├─ Scorecards
├─ Prompts
└─ Configurações
Relatórios
├─ Chamadas
├─ Agentes
├─ Filas
├─ Campanhas
└─ Consumo
Administração
├─ Usuários
├─ Perfis
└─ Configurações
```
Itens sem permissão não aparecem.
---
# 170. CAMPANHA WIZARD
Criar:
```text
1. Geral
2. Telefonia
3. Discagem
4. Horários
5. Gravação e IA
6. Leads
7. Revisão
```
---
# 171. DASHBOARD CAMPANHA
Mostrar:
```text
Status
CPS configurado
CPS atual
Concurrent
Pacing
Originando
Ringing
Atendidas
Esperando agente
Conectadas
Agentes disponíveis
Agentes ocupados
Wrap-up
Pausados
Answer Rate
Abandon Rate
TME
TMA
Leads restantes
Leads processados
```
---
# 172. STATUS UI
Utilizar badges consistentes.
Campanhas:
```text
DRAFT
cinza
READY
azul
RUNNING
verde
PAUSED
amarelo
DRAINING
laranja
STOPPED
vermelho
COMPLETED
verde escuro
ERROR
vermelho
```
---
# 173. TABELAS
Criar:
```text
Search
Filters
Sort
Pagination
Column Visibility
Row Actions
Bulk Actions quando aplicável
Export
```
Paginação server-side.
---
# 174. LIGHT/DARK
Implementar se não comprometer prioridades:
```text
Light
Dark
System
```
---
# 175. RESPONSIVIDADE
Priorizar:
```text
Desktop
Notebook
Tablet
```
Tela do agente deve funcionar bem em resoluções menores.
---
# 176. ACESSIBILIDADE
Implementar:
```text
labels
keyboard navigation
focus states
ARIA
contraste
```
Status não podem depender apenas da cor.
---
# 177. SEGREDOS
Criar:
```text
.env
.env.example
.gitignore
```
`.env` nunca no Git.
Secrets:
```text
POSTGRES
REDIS
JWT
ENCRYPTION KEY
ESL
FREESWITCH_PAT
AI provider keys
SMTP
S3
```
---
# 178. CREDENCIAIS SIP
Criptografar em repouso:
```text
AES-256-GCM
```
ou equivalente.
Master key fora do PostgreSQL.
---
# 179. AI KEYS
Mesmo tratamento.
Nunca logar.
Nunca devolver inteiro após salvar.
---
# 180. COMMAND INJECTION
Nunca concatenar input do usuário diretamente em:
```text
originate
uuid_transfer
bridge
sofia
callcenter_config
```
Criar builders seguros.
Validar:
```text
gateway
phone
queue
agent
extension
context
```
---
# 181. SQL SECURITY
Queries parametrizadas.
Nunca concatenar SQL com input.
---
# 182. HTTP SECURITY
Implementar:
```text
CSP
CORS restritivo
CSRF quando necessário
HSTS quando HTTPS
X-Content-Type-Options
Referrer-Policy
input validation
```
---
# 183. FIREWALL LOCAL
Utilizar nftables quando apropriado.
Antes de alterar:
```bash
ss -tnp
ip addr
ip route
```
Preservar SSH.
Não alterar firewalls externos.
---
# 184. PORTAS SENSÍVEIS
Não expor publicamente:
```text
5432 PostgreSQL
6379 Redis
8021 Event Socket
```
SIP deve ser restrito às origens necessárias.
---
# 185. DIALER SIMULATION
Inicialmente:
```text
DIALER_SIMULATION=true
```
Nesse modo:
NÃO realizar chamadas PSTN reais.
Simular:
```text
ANSWER
BUSY
NO_ANSWER
FAILED
RINGING
answer delay
talk time
```
---
# 186. REAL OUTBOUND SAFETY
Para habilitar chamadas reais exigir duas condições:
```text
DIALER_SIMULATION=false
```
e:
```text
ALLOW_REAL_OUTBOUND_CALLS=true
```
Não ativar automaticamente.
---
# 187. HEALTH CHECKS
Criar:
```text
/api/health
/api/health/live
/api/health/ready
```
Verificar:
```text
API
PostgreSQL
Redis
FreeSWITCH
ESL
Object Storage
Workers
```
Falha de provider externo de IA não deve necessariamente tornar API indisponível.
---
# 188. PROMETHEUS
Criar:
```text
/metrics
```
Métricas:
```text
b2bcall_calls_total
b2bcall_active_calls
b2bcall_tenant_active_calls
b2bcall_campaign_cps
b2bcall_campaign_pacing
b2bcall_agents_available
b2bcall_queue_waiting
b2bcall_ai_jobs_pending
b2bcall_ai_jobs_failed
b2bcall_ai_transcription_seconds
b2bcall_esl_connected
```
---
# 189. LOGGING
Logs JSON estruturados.
Contexto:
```text
request_id
tenant_id
user_id
call_id
attempt_id
campaign_id
ai_job_id
```
Nunca secrets.
---
# 190. Migrations
Toda alteração de banco deve usar migration.
Não fazer alterações manuais não versionadas.
---
# 191. TABELAS PRINCIPAIS
Planejar no mínimo:
```text
tenants
tenant_memberships
plans
plan_versions
tenant_subscriptions
entitlements
plan_entitlements
tenant_entitlement_overrides
price_books
price_book_items
rate_decks
rate_deck_entries
billing_periods
billing_statements
billing_statement_items
usage_events
rated_usage_items
users
sessions
roles
permissions
user_roles
role_permissions
telephony_nodes
tenant_telephony_assignments
extensions
trunks
sip_profiles
dialplans
dialplan_versions
agents
agent_sessions
agent_state_events
pause_reasons
agent_pause_events
queues
queue_agents
campaigns
campaign_schedules
campaign_agents
lead_imports
leads
dial_attempts
callbacks
dispositions
suppression_list
calls
call_legs
call_events
recordings
ai_providers
ai_models
ai_prompt_templates
ai_prompt_versions
ai_jobs
call_transcriptions
call_transcript_segments
call_ai_analyses
quality_scorecards
quality_scorecard_items
quality_evaluations
freeswitch_config_versions
audit_logs
application_settings
```
---
# 192. ÍNDICES
Criar índices tenant-aware:
```text
(tenant_id, status)
(tenant_id, created_at)
(tenant_id, campaign_id, status)
(tenant_id, phone_normalized)
(tenant_id, call_id)
(tenant_id, agent_id)
(tenant_id, queue_id)
```
---
# 193. GRANDES VOLUMES
Projetar para milhões de:
```text
calls
call_events
leads
usage_events
```
Não carregar tudo na memória.
Não usar relatórios sem paginação.
---
# 194. PARTITIONING READY
Preparar arquitetura futura para partição temporal:
```text
calls
call_events
usage_events
audit_logs
```
Sem complexidade prematura.
---
# 195. RECONCILIAÇÃO ESL
Se conexão cair:
```text
reconnect com exponential backoff
```
Após reconectar:
```text
resubscribe
reconcile calls
reconcile agents
reconcile queues
reconcile registrations
reconcile gateways
```
---
# 196. RECOVERY
Após restart dos workers:
```text
recover RUNNING campaigns
recover locks
release expired lead reservations
reconcile calls
resume safely
```
---
# 197. BACKUP
Criar:
```text
scripts/backup.sh
scripts/restore.sh
```
Backup:
```text
PostgreSQL
FreeSWITCH config
application config
```
Object Storage deve ter estratégia própria.
---
# 198. INSTALL SCRIPT
Criar:
```text
scripts/install.sh
```
Fluxo:
```text
verificar Debian
instalar dependências
instalar Docker
preparar diretórios
gerar secrets
subir PostgreSQL
subir Redis
build FreeSWITCH
migrations
seed
subir serviços
health checks
testes básicos
```
---
# 199. FIRST LOGIN
Criar Platform Super Admin inicial.
Senha aleatória forte.
Salvar uma única vez em:
```text
FIRST_LOGIN.txt
```
Permissão:
```text
600
```
Forçar troca no primeiro login.
---
# 200. SEED
Criar:
```text
platform_super_admin
tenant_admin
supervisor
agent
permissions
pausas básicas
dispositions básicas
```
---
# 201. DEMO DATA
Somente quando:
```text
SEED_DEMO_DATA=true
```
Em produção:
```text
false
```
---
# 202. TESTES
Criar:
```text
unit
integration
E2E
simulation
```
---
# 203. TESTE MULTI-TENANT
Criar:
```text
Tenant A
Tenant B
Tenant C
```
Garantir isolamento completo.
---
# 204. TESTE RLS
User Tenant A tentando acessar dado Tenant B:
resultado obrigatório:
```text
403
```
ou:
```text
404
```
Nunca dado do Tenant B.
---
# 205. TESTE QUOTA RAMAIS
Tenant:
```text
max_extensions = 10
```
Após 10:
11º deve falhar.
---
# 206. TESTE QUOTA AGENTES
Tenant:
```text
max_agents = 20
```
21º deve falhar.
---
# 207. TESTE CPS TENANT
Tenant:
```text
max_cps = 5
```
Múltiplas campanhas somadas não podem ultrapassar 5 CPS.
---
# 208. TESTE CONCURRENT TENANT
Tenant:
```text
max_concurrent_calls = 20
```
Duas campanhas juntas não podem ultrapassar 20.
---
# 209. TESTE LEAD DUPLICADO
Múltiplos workers concorrendo.
Resultado:
```text
nenhum lead originado duas vezes simultaneamente
```
---
# 210. TESTE PAUSE CAMPAIGN
Campaign:
```text
PAUSED
```
não deve gerar novo originate.
---
# 211. TESTE BILLING
Cenário:
```text
Tenant A
10 extensions
5 agents
2 trunks
100 calls
350 minutos
120 minutos transcription
50 AI analyses
```
Rating Engine deverá produzir itens financeiros correspondentes.
---
# 212. TESTE BILLING IMUTÁVEL
Depois de fechar mês:
alteração de preço não pode modificar statement fechado.
---
# 213. TESTE AI PROVIDERS
Criar mocks:
```text
OpenAIProvider Mock
AnthropicProvider Mock
```
CI não deve depender de APIs reais.
---
# 214. TESTE AI 429
Provider retorna:
```text
429
```
Worker deve:
```text
retry com backoff
```
e não perder job.
---
# 215. TESTE RECORDING
Validar:
```text
tenant_id
call_id
path
checksum
authorization
```
---
# 216. GIT
Inicializar Git.
Commits organizados:
```text
feat: bootstrap b2bcall saas architecture
feat: add multi tenant isolation
feat: add subscriptions and entitlements
feat: add freeswitch core
feat: add event socket integration
feat: add callcenter integration
feat: add predictive dialer
feat: add recording pipeline
feat: add ai provider abstraction
feat: add transcription pipeline
feat: add call intelligence
feat: add usage metering
feat: add rating engine
feat: add monthly billing
feat: add realtime monitoring
feat: harden tenant security
```
---
# 217. DOCUMENTAÇÃO
Criar:
```text
README.md
TODO.md
CHANGELOG.md
docs/ARCHITECTURE.md
docs/SAAS_MULTI_TENANCY.md
docs/TENANT_ISOLATION.md
docs/NETWORK_ARCHITECTURE.md
docs/FREESWITCH.md
docs/MOD_CALLCENTER.md
docs/EVENT_SOCKET.md
docs/XML_CURL.md
docs/OPENSIPS.md
docs/PREDICTIVE_DIALER.md
docs/RECORDING.md
docs/AI_ARCHITECTURE.md
docs/AI_PROVIDERS.md
docs/BILLING.md
docs/RATING_ENGINE.md
docs/DATABASE.md
docs/SECURITY.md
docs/OPERATIONS.md
docs/BACKUP_RESTORE.md
docs/TROUBLESHOOTING.md
```
---
# 218. TODO.MD
Criar imediatamente.
Fases:
```text
PHASE 01 Infrastructure
PHASE 02 SaaS Core
PHASE 03 Tenant Isolation
PHASE 04 Authentication / RBAC
PHASE 05 FreeSWITCH
PHASE 06 Telephony
PHASE 07 Call Center
PHASE 08 Predictive Dialer
PHASE 09 Recordings
PHASE 10 AI
PHASE 11 Usage Metering
PHASE 12 Billing
PHASE 13 Frontend
PHASE 14 Reports
PHASE 15 Security
PHASE 16 Tests
PHASE 17 Final Validation
```
Só marcar:
```text
[x]
```
depois de implementar e testar.
---
# 219. NÃO PARAR APÓS PLANEJAMENTO
Depois de criar:
```text
TODO.md
docs/ARCHITECTURE.md
```
continue imediatamente.
Não entregue somente arquitetura.
---
# 220. QUANDO ENCONTRAR ERRO
Processo:
```text
detectar
diagnosticar
corrigir
testar
documentar
continuar
```
Não abandonar o projeto por erro em uma fase.
---
# 221. BLOQUEIOS NÃO GLOBAIS
Se FreeSWITCH ainda não puder ser instalado:
continue:
```text
database
SaaS core
RBAC
billing
frontend
AI abstraction
tests
```
Depois volte.
---
# 222. QUALITY GATE BACKEND
Executar:
```text
lint
typecheck
unit tests
integration tests
E2E tests
tenant isolation tests
quota tests
dialer simulation tests
billing tests
AI tests
```
---
# 223. QUALITY GATE INFRA
Executar:
```text
docker compose config
docker compose ps
health checks
```
FreeSWITCH:
```bash
fs_cli -x "status"
fs_cli -x "show calls"
fs_cli -x "show channels"
fs_cli -x "sofia status"
fs_cli -x "callcenter_config queue list"
```
---
# 224. SECURITY QUALITY GATE
Validar:
```text
tenant A não vê tenant B
PostgreSQL não público
Redis não público
ESL não público
AI keys criptografadas
SIP passwords criptografadas
FREESWITCH_PAT fora do Git
.env fora do Git
RBAC funcionando
RLS funcionando
rate limit funcionando
IDOR protegido
```
---
# 225. CRITÉRIO DE ACEITE SAAS
Preciso conseguir:
1. criar Tenant;
2. definir plano;
3. definir limite de ramais;
4. definir limite de agentes;
5. definir limite de trunks;
6. definir limite CPS;
7. definir chamadas simultâneas;
8. criar tenant admin;
9. entrar como tenant admin;
10. criar recursos isolados;
11. visualizar consumo;
12. visualizar valor estimado;
13. alterar plano;
14. suspender tenant.
---
# 226. CRITÉRIO DE ACEITE TELEFONIA
Preciso:
1. cadastrar ramal;
2. registrar;
3. visualizar status;
4. cadastrar trunk;
5. visualizar status;
6. cadastrar fila;
7. cadastrar agente;
8. login agente;
9. pausa;
10. retorno da pausa;
11. chamada de teste;
12. CDR.
---
# 227. CRITÉRIO DE ACEITE DISCADOR
Preciso:
1. criar campanha;
2. selecionar trunk;
3. selecionar fila;
4. configurar CPS;
5. importar CSV;
6. iniciar;
7. visualizar pacing;
8. respeitar CPS campanha;
9. respeitar CPS tenant;
10. respeitar concurrent tenant;
11. pausar;
12. drain;
13. stop;
14. gerar relatório.
---
# 228. CRITÉRIO DE ACEITE IA
Preciso:
1. abrir IA → Providers;
2. cadastrar OpenAI;
3. cadastrar Anthropic;
4. cadastrar API key;
5. testar provider;
6. cadastrar modelos;
7. selecionar provider de transcrição;
8. selecionar provider de análise;
9. habilitar por tenant;
10. habilitar por campanha;
11. gravar chamada;
12. transcrever;
13. gerar segmentos;
14. gerar resumo;
15. gerar sentimento;
16. gerar tópicos;
17. gerar score;
18. visualizar tudo;
19. contabilizar uso;
20. contabilizar custo.
---
# 229. CRITÉRIO DE ACEITE BILLING
Preciso:
1. criar plano;
2. criar versão;
3. criar price book;
4. configurar preço base;
5. preço por ramal;
6. preço por agente;
7. preço por trunk;
8. preço por minuto;
9. preço IA;
10. associar tenant;
11. registrar usage;
12. rated usage;
13. visualizar mês atual;
14. fechar período;
15. gerar statement;
16. exportar PDF/CSV;
17. manter fechamento imutável.
---
# 230. PRIMEIRA AÇÃO
Leia este arquivo inteiro.
Depois:
```bash
pwd
ls -lah
cat /etc/os-release
uname -a
ip addr
ip route
df -h
lsblk
free -h
nproc
```
Verifique:
```text
b2blogo.png
```
Verifique somente a presença de:
```text
FREESWITCH_PAT
```
Não exiba a chave.
---
# 231. PRIMEIROS ARQUIVOS
Criar:
```text
TODO.md
docs/ARCHITECTURE.md
docs/SAAS_MULTI_TENANCY.md
docs/DATABASE.md
docs/SECURITY.md
```
Não parar depois.
---
# 232. ORDEM DE IMPLEMENTAÇÃO
Executar aproximadamente:
```text
Inspect Server
Git
Docker
PostgreSQL
Redis
Monorepo
SaaS Core
Tenant Isolation
PostgreSQL RLS
Plans / Entitlements
Authentication
RBAC
FreeSWITCH
Event Socket
XML Curl
Extensions
Trunks
Dialplan
mod_callcenter
Queues
Agents
Pauses
Realtime Monitoring
Campaigns
Leads
CPS Limiter
Predictive Engine
CDR
Recording
Object Storage
AI Provider Layer
Transcription
Call Analysis
Quality Scorecards
Usage Metering
Rating Engine
Monthly Billing
Frontend Polish
Reports
Security
Simulation
Tests
Final Validation
```
---
# 233. PRINCÍPIOS FUNDAMENTAIS
Sempre prefira:
```text
multi-tenant desde o início
>
adicionar tenant depois
PostgreSQL RLS
+
authorization
>
confiar somente em WHERE
versioned pricing
>
editar preço histórico
immutable usage ledger
>
reconstruir billing de forma improvisada
FreeSWITCH native features
>
reinventar telefonia
mod_callcenter
>
ACD custom desnecessário
Event Socket
>
polling
bgapi
>
originates síncronos
predictive pacing
>
loop simples
provider abstraction
>
OpenAI hardcoded
async AI jobs
>
IA bloqueando call flow
stereo recording
>
speaker identification fraco
structured AI results
>
texto livre
encrypted secrets
>
plain text
real data
>
mock
tests
>
presunção
security controls
>
bypass de permissões
```
---
# 234. RESULTADO FINAL
O produto final deverá ser:
# B2BCall
um SaaS capaz de atender diversos tenants, cada um com:
```text
seus usuários
seus ramais
seus agentes
suas filas
seus trunks
suas campanhas
seus leads
suas chamadas
suas gravações
suas transcrições
suas análises IA
suas quotas
seu consumo
seu billing
```
com isolamento completo.
---
# 235. RELATÓRIO FINAL
Somente depois dos quality gates apresentar:
```text
B2BCall Version:
Git Commit:
Application URL:
Docker Version:
PostgreSQL Version:
Redis Version:
FreeSWITCH Version:
Containers:
...
FreeSWITCH:
ONLINE / OFFLINE
ESL:
CONNECTED / DISCONNECTED
Tenants:
...
AI Providers:
...
Billing:
OPERATIONAL / PARTIAL / FAILED
Tests:
Unit:
Integration:
E2E:
Tenant Isolation:
Dialer Simulation:
Billing:
AI:
Security Checks:
...
Remaining Issues:
...
```
Não esconder pendências.
---
# 236. REGRA FINAL
Trabalhe de forma autônoma dentro das permissões fornecidas pelo Claude Code.
Não tente burlar ou remover mecanismos de autorização.
Não acesse outros servidores.
Não escaneie a rede.
Não utilize SSH contra outros hosts.
Não procure credenciais externas.
Não habilite chamadas PSTN reais automaticamente.
Não entregue somente documentação.
Não entregue somente frontend.
Não entregue somente FreeSWITCH.
Implemente progressivamente.
Teste continuamente.
Corrija os erros.
Atualize o `TODO.md`.
Faça commits organizados.
Continue pelas próximas fases disponíveis.
O objetivo final é transformar este servidor em uma instalação funcional do:
# B2BCall
## SaaS Multi-Tenant + FreeSWITCH + Predictive Dialer + Call Center + Recording + AI + Billing