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

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:

  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:

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:

  1. gerar;
  2. validar XML;
  3. versionar;
  4. ativar;
  5. reloadxml;
  6. verificar;
  7. 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:

  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:

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:

B2BCall

SaaS Multi-Tenant + FreeSWITCH + Predictive Dialer + Call Center + Recording + AI + Billing