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