- 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
58 KiB
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:
- analise;
- escolha a melhor;
- implemente;
- documente;
- teste;
- 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:
root
isso NÃO representa autorização para administrar outros servidores.
Regra obrigatória:
root neste servidor
!=
administrador da rede
4. PROIBIDO ACESSAR OUTROS SERVIDORES
Não acessar automaticamente outros servidores, equipamentos ou dispositivos.
É proibido utilizar:
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:
nmap
masscan
arp-scan
netdiscover
ou ferramenta equivalente para descobrir infraestrutura.
Não realizar sweeps em:
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:
/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:
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:
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:
agente.md
deverá ser considerado a raiz inicial do projeto.
Descubra usando:
pwd
Evite espalhar arquivos do projeto fora dessa estrutura sem necessidade.
10. LOGO
Existe no diretório do projeto:
b2blogo.png
Esta é a identidade visual oficial do B2BCall.
Não sobrescrever.
Não alterar o original.
Copiar para o frontend, por exemplo:
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:
FREESWITCH_PAT
Verifique somente a presença:
test -n "$FREESWITCH_PAT"
NUNCA execute:
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
Node.js
TypeScript
NestJS
Fastify
Frontend
Next.js
React
TypeScript
Tailwind CSS
shadcn/ui
TanStack Query
TanStack Table
Recharts
Lucide Icons
Banco
PostgreSQL
Cache / Jobs
Redis
BullMQ
Telefonia
FreeSWITCH
Reverse Proxy
nginx
13. ARQUITETURA MONOREPO
Estrutura sugerida:
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:
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:
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:
B2BCall Predictive Engine
=
decide quantas chamadas iniciar
FreeSWITCH mod_callcenter
=
decide para qual agente entregar chamadas atendidas
17. TOPOLOGIA SIP
Arquitetura esperada:
Internet
|
OpenSIPS
|
Rede SIP privada
|
FreeSWITCH
O FreeSWITCH NÃO deverá depender de IP SIP público.
Troncos poderão estar em rede privada:
FreeSWITCH
|
Rede privada
|
Carrier / SBC
18. RTP
Separar claramente:
SIP signaling
de:
RTP media
Preparar arquitetura compatível com:
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:
network_mode: host
ou:
macvlan / ipvlan
considerando SIP e grande range UDP de RTP.
Documentar decisão em:
docs/NETWORK_ARCHITECTURE.md
20. SOFIA PROFILES
Criar separação lógica como:
internal
opensips
carriers
quando adequado.
Configurações:
- IP;
- porta;
- transport;
- codecs;
- context;
- ACL;
- NAT;
- timers.
21. MOD_EVENT_SOCKET
Utilizar:
mod_event_socket
como principal integração de controle.
Criar serviço:
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:
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:
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:
callcenter::info
sofia::register
sofia::unregister
sofia::expire
sofia::gateway_state
Para AVMD:
avmd::start
avmd::beep
avmd::stop
24. NORMALIZAÇÃO DOS EVENTOS
Criar eventos internos B2BCall.
Exemplo:
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:
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:
FreeSwitchTelephonyProvider
26. MOD_XML_CURL
Utilizar principalmente para:
Directory
Dialplan
Criar:
b2bcall-fs-config
Fluxo:
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:
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:
tenants
Campos:
id UUID
code
slug
legal_name
trade_name
tax_id
status
timezone
locale
billing_currency
telephony_domain
created_at
updated_at
deleted_at
Status:
TRIAL
ACTIVE
SUSPENDED
PAST_DUE
CANCELLED
30. TENANT ID
Toda tabela tenant-scoped deverá possuir:
tenant_id UUID NOT NULL
Exemplos:
extensions
agents
queues
trunks
campaigns
leads
calls
recordings
ai_jobs
usage_events
31. NÃO CONFIAR NO TENANT_ID DO FRONTEND
Nunca confiar em:
{
"tenant_id": "..."
}
enviado pelo browser.
Resolver tenant a partir de:
authenticated user
+
tenant membership
+
authorized tenant context
32. POSTGRESQL RLS
Implementar:
ROW LEVEL SECURITY
nas tabelas críticas tenant-scoped.
Defense-in-depth:
RBAC
+
object authorization
+
tenant repositories
+
PostgreSQL RLS
33. TENANT CONTEXT
Criar mecanismo seguro de tenant na conexão/transaction PostgreSQL.
Exemplo conceitual:
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:
UNIQUE(extension_number)
globalmente.
Utilizar:
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:
telephony_nodes
Campos:
id
name
hostname
internal_ip
esl_host
esl_port
instance_id
status
max_sessions
max_cps
enabled
36. TENANT TELEPHONY ASSIGNMENT
Criar:
tenant_telephony_assignments
Inicialmente:
tenant
→
FreeSWITCH principal
Arquitetura deve permitir expansão futura.
37. MOD_CALLCENTER
Utilizar:
mod_callcenter
como ACD.
FreeSWITCH controla:
queues
agents
tiers
offering
distribution
bridging
wrap-up
B2BCall controla:
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:
app
freeswitch
ou solução equivalente.
39. RAMAIS
Criar tela:
Telefonia → Ramais
Tabela:
extensions
Campos:
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:
sofia::register
sofia::unregister
sofia::expire
Atualizar via WebSocket.
Evitar polling frequente.
41. TRONCOS
Criar:
Telefonia → Troncos
Tabela:
trunks
Campos:
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:
IP Authentication
Registration
Username/Password
42. STATUS DOS TRONCOS
Mostrar estados reais:
UP
DOWN
REGISTERED
TRYING
FAILED
UNREGISTERED
UNKNOWN
Consumir:
sofia::gateway_state
e comandos seguros quando necessário.
43. DIALPLAN
Criar:
Telefonia → Dialplan
Não fazer somente textarea.
Editor estruturado:
Context
Extension Name
Condition Field
Condition Expression
Actions
Anti-Actions
Continue
Order
Enabled
Salvar no PostgreSQL.
Gerar XML.
44. VERSIONAMENTO DIALPLAN
Criar:
dialplan_versions
Fluxo:
- gerar;
- validar XML;
- versionar;
- ativar;
reloadxml;- verificar;
- rollback se necessário.
45. AGENTES
Separar:
User
Agent
Extension
Criar:
agents
agent_sessions
agent_state_events
Todos tenant-scoped.
46. ESTADOS DOS AGENTES
Estados canônicos:
OFFLINE
LOGGED_IN
AVAILABLE
RESERVED
RINGING
IN_CALL
WRAP_UP
PAUSED
Mapear estados FreeSWITCH corretamente.
47. LOGIN DO AGENTE
Fluxo:
Login B2BCall
↓
Validar usuário
↓
Validar ramal
↓
Criar agent_session
↓
Configurar agent contact
↓
Configurar mod_callcenter
↓
Configurar tiers
↓
AVAILABLE
48. PAUSAS
Criar:
Call Center → Pausas
Tabelas:
pause_reasons
agent_pause_events
Campos:
tenant_id
name
code
description
max_duration
paid
enabled
Ao pausar:
FreeSWITCH → On Break
B2BCall → PAUSED
49. TELA DO AGENTE
Criar interface específica.
Mostrar:
Agente
Ramal
Fila
Campanha
Status
Tempo no status
Lead
Telefone
Tempo da chamada
Botões:
DISPONÍVEL
PAUSA
FINALIZAR PAUSA
LOGOUT
50. FILAS
Criar:
Call Center → Filas
Campos relevantes:
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:
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:
Queue
↓
Tier
↓
Agent
Campos:
tenant_id
queue_id
agent_id
level
position
53. WRAP-UP
Utilizar:
wrap-up-time
Enquanto em wrap-up:
agente não está disponível
O Predictive Dialer deve considerar isso.
54. MONITORAMENTO DAS FILAS
Criar:
Monitoramento → Filas
Mostrar em tempo real:
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:
Monitoramento → Ramais
Cada ramal deverá aparecer em card.
Convenção obrigatória:
CINZA
offline
VERDE
disponível
LARANJA
ocupado
AZUL
agente logado
VERMELHO
agente em pausa
Prioridade:
PAUSA
>
EM CHAMADA
>
AGENTE LOGADO
>
DISPONÍVEL
>
OFFLINE
Mostrar:
Ramal
Nome
Agente
Fila
Status
Tempo no estado
Campanha
Duração da chamada
56. QUOTAS SAAS
Criar sistema genérico de:
entitlements
Não espalhar regras:
if plan == PRO
pelo código.
Entitlements:
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:
active_extensions < max_extensions
Caso ultrapasse:
retornar erro de quota.
58. QUOTA DE AGENTES
Antes de criar agente:
active_agents < max_agents
59. QUOTA DE TRONCOS
Antes de criar trunk:
active_trunks < max_trunks
60. CPS TENANT
Cada tenant possui:
max_cps
Esse limite deve considerar a soma de todas as campanhas do tenant.
61. CHAMADAS SIMULTÂNEAS TENANT
Cada tenant possui:
max_concurrent_calls
Mesmo que tenha várias campanhas, o total não pode ultrapassar.
62. HIERARQUIA DE LIMITES
Toda originação deve respeitar:
GLOBAL
↓
TELEPHONY NODE
↓
TENANT
↓
TRUNK
↓
CAMPAIGN
CPS efetivo:
MIN(
global_available_cps,
node_available_cps,
tenant_available_cps,
trunk_available_cps,
campaign_available_cps
)
63. CAMPANHAS
Criar:
Discador → Campanhas
Campos:
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
DRAFT
READY
WAITING_SCHEDULE
RUNNING
PAUSED
DRAINING
STOPPED
COMPLETED
ERROR
65. DRAINING
Ao selecionar:
DRAIN
não originar novas chamadas.
Permitir finalizar as existentes.
66. STOP
Por padrão:
STOP
=
não originar novas chamadas
+
deixar chamadas já conectadas terminarem
Não derrubar chamadas ativas automaticamente.
67. LEADS
Criar:
leads
Campos:
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
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:
nome,telefone
Joao Silva,48999999999
Maria Souza,11999999999
Wizard:
Upload
↓
Preview
↓
Mapeamento
↓
Validação
↓
Normalização
↓
Duplicados
↓
Importação
Mostrar:
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:
phone_original
phone_normalized
Inicialmente preparado para Brasil.
Arquitetura preparada para E.164.
71. LISTA DE BLOQUEIO
Criar:
Discador → Lista de Bloqueio
Tabela:
suppression_list
Tenant-scoped.
Antes de qualquer chamada:
CHECK SUPPRESSION LIST
obrigatório.
72. PREDICTIVE DIALER
Criar serviço:
PredictiveDialerEngine
Não implementar apenas:
for lead -> originate
Isso não é discador preditivo.
73. DADOS DO PREDICTIVE ENGINE
Considerar:
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:
elapsed_talk_time
+
historical talk time distribution
para estimar agentes disponíveis em:
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:
answer_probability
average_answer_delay
TMA
abandon_rate
Evitar oscilações violentas do pacing.
76. CÁLCULO CONCEITUAL
expected_agent_capacity =
available_agents
+
predicted_agents_becoming_available
expected_answers =
calls_to_originate * answer_probability
Objetivo:
expected_answers
≈
expected_agent_capacity
Aplicando:
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:
sleep()
como controle.
78. RESERVA DE LEADS
Evitar duplicidade.
Utilizar PostgreSQL:
FOR UPDATE SKIP LOCKED
ou solução transacional equivalente.
Fluxo:
READY
↓
RESERVED
↓
ORIGINATING
atômico.
79. LOCK DE CAMPANHA
Criar:
dialer:campaign:{id}
com:
TTL
ownership token
renewal
safe release
80. ORIGINATE
Utilizar:
bgapi originate
via ESL.
Não originar milhares de chamadas sincronamente.
81. IDENTIFICADORES DA CHAMADA
Criar antes do originate:
tenant_id
call_id
attempt_id
campaign_id
lead_id
origination_uuid
Enviar como channel variables:
b2bcall_tenant_id
b2bcall_call_id
b2bcall_attempt_id
b2bcall_campaign_id
b2bcall_lead_id
82. STATE MACHINE
CREATED
RESERVED
ORIGINATING
ORIGINATED
RINGING
ANSWERED
QUEUEING
AGENT_CONNECTED
COMPLETED
BUSY
NO_ANSWER
FAILED
ABANDONED
Persistir transições.
83. FLUXO DA CHAMADA PREDITIVA
Lead
↓
Reserve
↓
Predictive Engine
↓
CPS Limiter
↓
FreeSWITCH bgapi originate
↓
Sofia Gateway
↓
PSTN
Se atender:
ANSWER
↓
AVMD opcional
↓
mod_callcenter
↓
Queue
↓
Agent
↓
Bridge
84. ABANDONO
Se:
abandon_rate > target
reduzir pacing.
Se continuar:
modo conservador
Se atingir limite crítico:
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:
BUSY -> 15 min
NO_ANSWER -> 60 min
CONGESTION -> 5 min
FAILED -> 30 min
Nunca retry infinito.
87. AVMD
Utilizar opcionalmente:
mod_avmd
Não tratar como detector perfeito de humano/máquina.
Resultados internos quando possível:
HUMAN
MACHINE_BEEP
UNKNOWN
88. CALLBACK
Criar:
callbacks
Campos:
tenant_id
lead_id
campaign_id
agent_id
scheduled_at
timezone
preferred_agent
notes
status
Scheduler deverá reativar corretamente.
89. DISPOSIÇÕES
Criar:
Call Center → Disposições
Exemplos:
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:
recordings
Campos:
tenant_id
call_id
storage_provider
object_key
format
duration_seconds
channels
size_bytes
checksum
recorded_at
retention_until
status
91. FREESWITCH RECORDING
Utilizar:
record_session
ou mecanismo apropriado.
Preferencialmente gravar chamadas de Call Center em estéreo quando tecnicamente adequado:
RECORD_STEREO=true
Objetivo:
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:
ObjectStorageProvider
Suportar:
Local
S3 Compatible
Preparar para:
AWS S3
MinIO
93. STORAGE PATH
Usar estrutura segura, por exemplo:
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:
recording_retention_days
transcription_retention_days
por tenant/plano.
Scheduler deverá aplicar retenção.
95. INTELIGÊNCIA ARTIFICIAL
Criar módulo:
IA
Submenus:
Providers
Modelos
Prompts
Scorecards
Análises
Uso
Configurações
96. AI PROVIDER ABSTRACTION
Não hardcode OpenAI no domínio.
Criar abstração:
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:
OpenAI
Anthropic
Arquitetura deve permitir:
Google
Azure OpenAI
AWS Bedrock
modelos locais
outros providers
futuramente.
98. NOMENCLATURA
Na integração utilizar:
OpenAI API
e:
Anthropic API
Não amarrar o domínio ao produto:
ChatGPT
99. AI PROVIDERS TABLE
Criar:
ai_providers
Campos:
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
Bring Your Own Key
Tenant cadastra sua própria API key.
101. API KEYS
Criptografar em repouso usando:
AES-256-GCM
ou equivalente moderno.
Master key fora do PostgreSQL.
Nunca mostrar key inteira após salvar.
102. CAPABILITIES
Criar conceito:
TRANSCRIPTION
DIARIZATION
TEXT_ANALYSIS
STRUCTURED_OUTPUT
EMBEDDINGS
REALTIME_AUDIO
Nem todo provider terá todas as capacidades.
103. AI MODELS
Criar:
ai_models
Campos:
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:
TranscriptionProvider
Configuração:
provider
model
language
diarization
105. ANALYSIS PROVIDER
Separar de transcrição.
Permitir exemplo:
OpenAI → Transcrição
Anthropic → Análise
ou:
OpenAI → Transcrição
OpenAI → Análise
106. PIPELINE IA
Após hangup:
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:
ai_jobs
Tipos:
TRANSCRIPTION
ANALYSIS
REANALYSIS
Status:
PENDING
PROCESSING
COMPLETED
FAILED
RETRYING
CANCELLED
108. RETRY IA
Implementar:
retry
exponential backoff
dead-letter strategy
Limitar tentativas.
109. TRANSCRIÇÕES
Criar:
call_transcriptions
Campos:
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:
call_transcript_segments
Campos:
transcription_id
speaker
start_ms
end_ms
text
confidence optional
Speaker:
AGENT
CUSTOMER
UNKNOWN
111. SPEAKER MAPPING
Sempre que possível utilizar canais estéreo para identificar:
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:
call_ai_analyses
Resultado estruturado:
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:
{
"summary": "...",
"sentiment": "NEUTRAL",
"topics": [],
"objections": [],
"quality_score": 82,
"compliance_flags": [],
"action_items": []
}
Validar antes de persistir.
114. PROMPTS
Criar:
ai_prompt_templates
ai_prompt_versions
Prompts não devem ficar hardcoded.
115. PROMPT POR TENANT
Tenant poderá definir prompt próprio.
Exemplo:
analise esta chamada como atendimento de suporte
116. PROMPT POR CAMPANHA
Campanha poderá sobrescrever.
Exemplo cobrança:
promessa de pagamento
data prometida
objeções
Exemplo vendas:
interesse
produto
objeções
intenção de compra
117. SCORECARD
Criar:
quality_scorecards
quality_scorecard_items
quality_evaluations
Itens:
Saudação
Identificação
Empatia
Entendimento
Apresentação
Objeções
Encerramento
Compliance
Campos:
weight
description
evaluation_prompt
118. QA AUTOMÁTICO
Gerar:
score 0-100
por chamada.
Guardar:
score
criterion_scores
summary_justification
Não armazenar chain-of-thought do modelo.
119. DASHBOARD IA
Mostrar:
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:
Resumo
Timeline
Gravação
Transcrição
Análise IA
Eventos
Billing
121. PLAYER DE ÁUDIO
Implementar:
play
pause
timeline
duration
Se possível sincronizar transcrição.
122. PRIVACIDADE IA
Permitir:
AI OFF
TRANSCRIPTION ONLY
TRANSCRIPTION + ANALYSIS
por:
- tenant;
- campanha;
- fila.
123. REDACTION
Criar abstração:
SensitiveDataRedactor
Preparar para mascarar:
CPF
CNPJ
telefone
email
cartão
outros dados
antes de enviar ao provider quando política exigir.
124. AI USAGE METERING
Gerar usage:
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:
plans
plan_versions
Exemplo:
Starter
Professional
Enterprise
Preços e limites devem ser versionados.
127. SUBSCRIPTIONS
Criar:
tenant_subscriptions
Campos:
tenant_id
plan_version_id
status
started_at
ends_at
billing_cycle_anchor
currency
128. PRICE BOOKS
Criar:
price_books
price_book_items
Tipos de preço:
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:
rate_decks
rate_deck_entries
Campos:
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:
RatingEngine
Responsável por:
uso bruto
↓
regra de preço
↓
valor financeiro
Nunca calcular billing no frontend.
131. USAGE LEDGER
Criar tabela imutável:
usage_events
Campos:
id UUID
tenant_id
meter
quantity
unit
source_type
source_id
occurred_at
metadata
created_at
Exemplos:
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:
rated_usage_items
Campos:
tenant_id
usage_event_id
price_book_item_id
quantity
unit_price
amount
currency
pricing_version
133. CHAMADA FATURÁVEL
Guardar:
billable_seconds
billing_increment
rated_minutes
destination_rate
rated_amount
134. BILLING PERIOD
Criar:
billing_periods
Status:
OPEN
CALCULATING
READY
CLOSED
REOPENED
135. MONTHLY STATEMENTS
Criar:
billing_statements
billing_statement_items
Relatório mensal por tenant:
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:
Usage Statement
Billing Statement
Relatório de Consumo
Não afirmar automaticamente que se trata de:
NFCom
NFS-e
Nota Fiscal
Integração fiscal é outro módulo.
137. FECHAMENTO IMUTÁVEL
Depois de:
CLOSED
não recalcular silenciosamente.
Para corrigir:
REOPEN
com:
user
reason
audit
138. ESTIMATIVA DO MÊS
Tenant Dashboard deverá mostrar:
Valor estimado do mês
Mas deixar claro que é valor em aberto.
139. DASHBOARD DE QUOTAS
Mostrar:
Ramais
8 / 10
Agentes
15 / 20
Troncos
2 / 3
CPS
6 / 10
Chamadas simultâneas
18 / 25
140. PLATFORM SUPER ADMIN
Criar:
platform_super_admin
Pode:
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:
tenant_admin
Pode administrar somente seu tenant.
142. ROLES
Roles iniciais:
platform_super_admin
tenant_admin
supervisor
agent
Mas utilizar RBAC configurável.
143. RBAC
Criar:
roles
permissions
user_roles
role_permissions
Permitir roles customizadas.
144. ROLE SCOPE
Role possui:
PLATFORM
ou:
TENANT
Nunca permitir escopo global acidental.
145. PERMISSÕES
Criar permissões como:
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:
campaigns.view
não é suficiente.
Também verificar:
campaign.tenant_id == user.tenant_id
147. PROTEÇÃO IDOR
Um usuário tenant A tentando:
/api/calls/{uuid-tenant-b}
deve receber:
403
ou:
404
Nunca retornar dados.
148. AUTENTICAÇÃO
Login:
email
senha
Hash:
Argon2id
Implementar:
access token
refresh token
refresh rotation
logout
session revocation
password reset
forced password change
149. RATE LIMIT
Login:
5 tentativas/minuto/IP
ou estratégia segura equivalente.
Também:
rate per user
progressive blocking
audit
150. AUDIT LOG
Criar:
audit_logs
Campos:
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:
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:
mod_odbc_cdr
com PostgreSQL via ODBC.
Configurar fallback/spool para evitar perda silenciosa de CDR.
153. MODELO DE CHAMADAS
Criar:
calls
call_legs
call_events
dial_attempts
154. FIELDS CALL
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:
agent_answer_at - queue_enter_at
Separar tempo médio até abandono.
156. TMA
Principal:
SUM(talk_time) / answered_calls
Permitir indicador separado:
Talk Time + Wrap-Up
157. RELATÓRIO DE CHAMADAS
Filtros:
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:
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:
Recebidas
Atendidas
Abandonadas
TME
TMA
Service Level
Abandon Rate
160. RELATÓRIO CAMPANHA
Mostrar:
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:
Chamadas hoje
Atendidas
Em andamento
Esperando agente
Agentes disponíveis
Agentes ocupados
Agentes pausados
TME
TMA
Answer Rate
Abandon Rate
Também:
Consumo do plano
Valor estimado no mês
163. DASHBOARD PLATFORM
Mostrar:
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:
FreePBX
FusionPBX
painel Linux
Bootstrap antigo
sistema legado
165. DESIGN SYSTEM
Criar tokens para:
colors
typography
spacing
border radius
shadows
status colors
buttons
forms
badges
cards
tables
dialogs
charts
166. LAYOUT
Criar:
Sidebar
+
Topbar
+
Content
Sidebar recolhível.
167. LOGIN
Utilizar b2blogo.png.
Criar tela moderna.
Desktop poderá usar:
Brand B2BCall
|
Login Form
Responsiva.
168. MENU PLATFORM
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
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:
1. Geral
↓
2. Telefonia
↓
3. Discagem
↓
4. Horários
↓
5. Gravação e IA
↓
6. Leads
↓
7. Revisão
171. DASHBOARD CAMPANHA
Mostrar:
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:
DRAFT
cinza
READY
azul
RUNNING
verde
PAUSED
amarelo
DRAINING
laranja
STOPPED
vermelho
COMPLETED
verde escuro
ERROR
vermelho
173. TABELAS
Criar:
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:
Light
Dark
System
175. RESPONSIVIDADE
Priorizar:
Desktop
Notebook
Tablet
Tela do agente deve funcionar bem em resoluções menores.
176. ACESSIBILIDADE
Implementar:
labels
keyboard navigation
focus states
ARIA
contraste
Status não podem depender apenas da cor.
177. SEGREDOS
Criar:
.env
.env.example
.gitignore
.env nunca no Git.
Secrets:
POSTGRES
REDIS
JWT
ENCRYPTION KEY
ESL
FREESWITCH_PAT
AI provider keys
SMTP
S3
178. CREDENCIAIS SIP
Criptografar em repouso:
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:
originate
uuid_transfer
bridge
sofia
callcenter_config
Criar builders seguros.
Validar:
gateway
phone
queue
agent
extension
context
181. SQL SECURITY
Queries parametrizadas.
Nunca concatenar SQL com input.
182. HTTP SECURITY
Implementar:
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:
ss -tnp
ip addr
ip route
Preservar SSH.
Não alterar firewalls externos.
184. PORTAS SENSÍVEIS
Não expor publicamente:
5432 PostgreSQL
6379 Redis
8021 Event Socket
SIP deve ser restrito às origens necessárias.
185. DIALER SIMULATION
Inicialmente:
DIALER_SIMULATION=true
Nesse modo:
NÃO realizar chamadas PSTN reais.
Simular:
ANSWER
BUSY
NO_ANSWER
FAILED
RINGING
answer delay
talk time
186. REAL OUTBOUND SAFETY
Para habilitar chamadas reais exigir duas condições:
DIALER_SIMULATION=false
e:
ALLOW_REAL_OUTBOUND_CALLS=true
Não ativar automaticamente.
187. HEALTH CHECKS
Criar:
/api/health
/api/health/live
/api/health/ready
Verificar:
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:
/metrics
Métricas:
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:
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:
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:
(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:
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:
calls
call_events
usage_events
audit_logs
Sem complexidade prematura.
195. RECONCILIAÇÃO ESL
Se conexão cair:
reconnect com exponential backoff
Após reconectar:
resubscribe
reconcile calls
reconcile agents
reconcile queues
reconcile registrations
reconcile gateways
196. RECOVERY
Após restart dos workers:
recover RUNNING campaigns
recover locks
release expired lead reservations
reconcile calls
resume safely
197. BACKUP
Criar:
scripts/backup.sh
scripts/restore.sh
Backup:
PostgreSQL
FreeSWITCH config
application config
Object Storage deve ter estratégia própria.
198. INSTALL SCRIPT
Criar:
scripts/install.sh
Fluxo:
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:
FIRST_LOGIN.txt
Permissão:
600
Forçar troca no primeiro login.
200. SEED
Criar:
platform_super_admin
tenant_admin
supervisor
agent
permissions
pausas básicas
dispositions básicas
201. DEMO DATA
Somente quando:
SEED_DEMO_DATA=true
Em produção:
false
202. TESTES
Criar:
unit
integration
E2E
simulation
203. TESTE MULTI-TENANT
Criar:
Tenant A
Tenant B
Tenant C
Garantir isolamento completo.
204. TESTE RLS
User Tenant A tentando acessar dado Tenant B:
resultado obrigatório:
403
ou:
404
Nunca dado do Tenant B.
205. TESTE QUOTA RAMAIS
Tenant:
max_extensions = 10
Após 10:
11º deve falhar.
206. TESTE QUOTA AGENTES
Tenant:
max_agents = 20
21º deve falhar.
207. TESTE CPS TENANT
Tenant:
max_cps = 5
Múltiplas campanhas somadas não podem ultrapassar 5 CPS.
208. TESTE CONCURRENT TENANT
Tenant:
max_concurrent_calls = 20
Duas campanhas juntas não podem ultrapassar 20.
209. TESTE LEAD DUPLICADO
Múltiplos workers concorrendo.
Resultado:
nenhum lead originado duas vezes simultaneamente
210. TESTE PAUSE CAMPAIGN
Campaign:
PAUSED
não deve gerar novo originate.
211. TESTE BILLING
Cenário:
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:
OpenAIProvider Mock
AnthropicProvider Mock
CI não deve depender de APIs reais.
214. TESTE AI 429
Provider retorna:
429
Worker deve:
retry com backoff
e não perder job.
215. TESTE RECORDING
Validar:
tenant_id
call_id
path
checksum
authorization
216. GIT
Inicializar Git.
Commits organizados:
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:
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:
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:
[x]
depois de implementar e testar.
219. NÃO PARAR APÓS PLANEJAMENTO
Depois de criar:
TODO.md
docs/ARCHITECTURE.md
continue imediatamente.
Não entregue somente arquitetura.
220. QUANDO ENCONTRAR ERRO
Processo:
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:
database
SaaS core
RBAC
billing
frontend
AI abstraction
tests
Depois volte.
222. QUALITY GATE BACKEND
Executar:
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:
docker compose config
docker compose ps
health checks
FreeSWITCH:
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:
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:
- criar Tenant;
- definir plano;
- definir limite de ramais;
- definir limite de agentes;
- definir limite de trunks;
- definir limite CPS;
- definir chamadas simultâneas;
- criar tenant admin;
- entrar como tenant admin;
- criar recursos isolados;
- visualizar consumo;
- visualizar valor estimado;
- alterar plano;
- suspender tenant.
226. CRITÉRIO DE ACEITE TELEFONIA
Preciso:
- cadastrar ramal;
- registrar;
- visualizar status;
- cadastrar trunk;
- visualizar status;
- cadastrar fila;
- cadastrar agente;
- login agente;
- pausa;
- retorno da pausa;
- chamada de teste;
- CDR.
227. CRITÉRIO DE ACEITE DISCADOR
Preciso:
- criar campanha;
- selecionar trunk;
- selecionar fila;
- configurar CPS;
- importar CSV;
- iniciar;
- visualizar pacing;
- respeitar CPS campanha;
- respeitar CPS tenant;
- respeitar concurrent tenant;
- pausar;
- drain;
- stop;
- gerar relatório.
228. CRITÉRIO DE ACEITE IA
Preciso:
- abrir IA → Providers;
- cadastrar OpenAI;
- cadastrar Anthropic;
- cadastrar API key;
- testar provider;
- cadastrar modelos;
- selecionar provider de transcrição;
- selecionar provider de análise;
- habilitar por tenant;
- habilitar por campanha;
- gravar chamada;
- transcrever;
- gerar segmentos;
- gerar resumo;
- gerar sentimento;
- gerar tópicos;
- gerar score;
- visualizar tudo;
- contabilizar uso;
- contabilizar custo.
229. CRITÉRIO DE ACEITE BILLING
Preciso:
- criar plano;
- criar versão;
- criar price book;
- configurar preço base;
- preço por ramal;
- preço por agente;
- preço por trunk;
- preço por minuto;
- preço IA;
- associar tenant;
- registrar usage;
- rated usage;
- visualizar mês atual;
- fechar período;
- gerar statement;
- exportar PDF/CSV;
- manter fechamento imutável.
230. PRIMEIRA AÇÃO
Leia este arquivo inteiro.
Depois:
pwd
ls -lah
cat /etc/os-release
uname -a
ip addr
ip route
df -h
lsblk
free -h
nproc
Verifique:
b2blogo.png
Verifique somente a presença de:
FREESWITCH_PAT
Não exiba a chave.
231. PRIMEIROS ARQUIVOS
Criar:
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:
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:
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:
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:
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: