Files
b2bcall/docs/RELATORIO_FINAL.md
B2BCall Bootstrap a10a40a489 docs: registrar bugs encontrados na verificação real em navegador
Usuário testou em produção e confirmou que os dois bugs do commit
anterior (Content-Type em requisições sem corpo, DELETE de supressão sem
motivo) estão corrigidos. Atualiza TODO.md/RELATORIO_FINAL.md para
refletir a verificação visual como concluída, e documenta a lição em
TROUBLESHOOTING.md: teste via curl prova que o backend funciona, não que
o frontend consegue falar com ele.
2026-08-27 20:52:48 -03:00

7.1 KiB

B2BCall — Relatório Final da Implementação

Formato conforme agente.md seção 96. Gerado em 2026-08-27 contra o ambiente real em execução (Lab-FSCore-API, 10.10.32.142).

B2BCall version:   0.1.0
Asterisk version:  22.10.1
Node version:      v24.20.0
PostgreSQL version: 17 (postgres:17-alpine)
Docker version:    29.7.2 (Compose v5.5.0)

Containers

Container Status
b2bcall-postgres healthy
b2bcall-redis healthy
b2bcall-asterisk healthy
b2bcall-api healthy
b2bcall-frontend healthy
b2bcall-nginx healthy
b2bcall-asterisk-events up (sem healthcheck HTTP formal — worker sem porta exposta)
b2bcall-dialer-worker up (idem)

URLs

  • Interface web: http://10.10.32.142/
  • API: http://10.10.32.142/api
  • Health: http://10.10.32.142/api/health
  • Métricas (Prometheus, autenticado, uso interno): http://10.10.32.142/api/metrics

Super admin

Ver arquivo local CREDENCIAIS.txt (fora do git, entregue separadamente — nunca colocamos senha em texto puro em um arquivo versionado, mesmo em um Git privado). Contém: usuário/senha do super_admin web e as credenciais do PostgreSQL/Redis.

Health

$ bash scripts/healthcheck.sh
docker compose ps:        8/8 containers up
/api/health:               {"status":"ok","postgres":"up","redis":"up","asterisk":"up"}
Asterisk core show uptime: OK
pjsip show endpoints:      OK (comando responde; sem endpoints — fixtures de teste removidos)
nftables (b2bcall_fw):     ativo

Aceite Asterisk (seção 93)

$ asterisk -rx "core show version"
Asterisk 22.10.1 built by root @ buildkitsandbox on a x86_64 running Linux on 2026-08-27 13:32:29 UTC

$ asterisk -rx "core show uptime"
System uptime: 5 hours, 43 minutes, 19 seconds
Last reload: 6 minutes, 54 seconds

$ asterisk -rx "pjsip show endpoints"
No objects found.
(esperado: todos os troncos/ramais de teste foram removidos ao final de cada fase)

$ asterisk -rx "pjsip show contacts"
No objects found.

$ asterisk -rx "queue show"
No queues.

Comunicação API → AMI → Asterisk: validada via GET /api/asterisk/status{"amiControlConnection":"up","asteriskEventsHeartbeat":"up",...}.

Tests

Build/typecheck (pnpm -r build, 7 workspaces):  PASS
Lint (api, frontend):                            PASS
Unit tests:
  apps/api        13/13 PASS
  apps/dialer-worker 33/33 PASS
docker compose config:                           válida
docker compose ps:                                8/8 up
scripts/healthcheck.sh:                           PASS

Aceite de segurança (seção 92) — verificado ao vivo, não só por inspeção

Item Resultado
Nenhuma senha no Git (git log --all -- .env vazio)
Nenhum .env commitado
PostgreSQL não público (127.0.0.1:5432 apenas)
Redis não público (nenhuma porta publicada)
AMI não público (nftables bloqueia ens18:5038)
ARI não público (nftables bloqueia ens18:8088/8089)
Rate limit funcionando (7ª tentativa de login seguida → HTTP 429)
RBAC funcionando no backend (papel agent → 403 em /asterisk/status, /trunks, /users)
Agent não acessa configuração do Asterisk
Agent não eleva a própria permissão
SQL injection protegida (Prisma parametrizado em toda parte)
Path traversal protegido (nenhum path de arquivo construído a partir de input do usuário)
Logs sem credenciais (redação do pino confirmada, varredura real sem vazamento)

Prova do dialer (seção 91)

  • CPS configurado nunca excedido em nenhuma janela de 1s: (simulation-harness.spec.ts)
  • Concorrência máxima da campanha nunca excedida: (idem)
  • Pacing reage/reduz quando abandono sobe: (idem + bug real corrigido durante o desenvolvimento, ver docs/PREDICTIVE_DIALER.md)
  • Reprodutibilidade (mesma seed → mesmo resultado):
  • Reserva de lead atômica (sem discagem dupla): (FOR UPDATE SKIP LOCKED, testado na Fase 6 contra Postgres real)
  • Campanha pausada não gera chamada nova: (testado na Fase 6)
  • Lead suprimido não é discado: (isSuppressed pré-originação, testado na Fase 6)
  • Campanha fora do horário não discou: (schedule.spec.ts, 6 testes)
  • Worker reiniciado recupera operação: ⚠️ parcial — reconciliation.ts tem teste unitário e roda em produção a cada 60s, mas o cenário "matar o processo de verdade no meio de uma chamada" não foi exercitado nesta sessão (ver Pending).

Pending

Itens genuinamente pendentes, nunca escondidos:

  1. Integration tests automatizados (Postgres/Redis/AMI reais via testcontainers ou equivalente) não existem como suíte formal — toda a verificação de integração foi feita manualmente contra containers reais a cada fase (real, mas não repetível em CI sem intervenção).
  2. Recuperação após kill real do worker não foi testada nesta sessão (só via teste unitário da lógica de reconciliação).
  3. scripts/install.sh/update.sh não foram testados de ponta a ponta num servidor limpo (o servidor atual já estava provisionado) — validados por inspeção linha a linha contra os comandos manuais já executados.
  4. Verificação visual em navegador real — feita posteriormente pelo usuário em produção. Confirmou que o curl sozinho não é suficiente: achou dois bugs reais de integração frontend↔API invisíveis a testes via curl (Content-Type em requisições sem corpo quebrando todo botão de ação; DELETE de supressão sem forma de enviar o motivo exigido). Ambos corrigidos, usuário confirmou funcionamento. Ver docs/TROUBLESHOOTING.md.
  5. Tela de Callbacks no frontend não existe — o agendamento e a reativação automática funcionam via API/worker (POST /agent-console/ dispose, GET /api/callbacks, callback-sweep.ts), mas não há uma tela dedicada para visualizar a fila de callbacks pendentes.
  6. AMD (detecção de secretária eletrônica) — campo existe no schema, detecção real via app AMD do Asterisk não integrada à originação.
  7. Correlação automática CDR↔DialAttempt para chamadas reais (não simuladas) além do timeout de segurança de reconciliação.
  8. WebSocket real — painéis de monitoramento usam polling (5-15s), não um gateway WebSocket dedicado.
  9. OpenSIPS não implantado — decisão documentada em docs/OPENSIPS.md (não resolve nenhum problema real do ambiente atual de instância única).
  10. HTTPS não configurado (rede privada, sem IP público) — passo a passo em docs/OPERATIONS.md.
  11. asterisk-events/dialer-worker não têm healthcheck Docker formal (workers em background sem porta HTTP própria).
  12. Rotação de SECRETS_MASTER_KEY não é automatizada — exigiria redescriptografar todos os segredos de tronco/ramal manualmente.

Nenhum destes itens bloqueia o uso do sistema para o que foi pedido (discador preditivo funcional, call center completo, frontend completo, segurança e backup); são lacunas de robustez/automação a considerar antes de operar com volume real de produção.