- infrastructure/freeswitch/Dockerfile: debian:trixie-slim + SignalWire packaged freeswitch-meta-vanilla, avoiding a C/C++ build on a 1.9GB RAM VM - FREESWITCH_PAT used only via Docker BuildKit secret, apt credentials file created and deleted within the same RUN — verified absent from the final image with docker history - minimal module set (agente.md secao 15): sofia, event_socket, commands, dptools, callcenter, avmd, curl, local_stream, etc. mod_xml_curl installed but disabled — it refuses to load without a configured gateway-url, which will exist once b2bcall-fs-config is built - entrypoint.sh rotates the Event Socket password away from the 'ClueCon' default at container runtime (never baked into the image); fails loudly if ESL_PASSWORD is unset - port 8021 not published to the host; only reachable from other containers on the compose network - found and fixed: freeswitch-conf-vanilla is a Recommends (not a Depends) of freeswitch-meta-vanilla, so --no-install-recommends silently produced an empty /etc/freeswitch and a crash loop - verified end-to-end: fs_cli status via ESL with the custom password, default password rejected, expected modules loaded, healthcheck green, ~44MB RAM usage - docs/FREESWITCH.md, docs/NETWORK_ARCHITECTURE.md (network_mode decision deferred until a real SIP trunk exists)
4.2 KiB
4.2 KiB
TODO — B2BCall
PHASE 01 — Infrastructure
- Diagnóstico do servidor (Debian 13, 2 vCPU, ~1.9GB RAM, 26GB disco livre)
- Docker + Docker Compose instalados
- Estrutura de monorepo criada (apps/, packages/, infrastructure/, scripts/, docs/)
- PostgreSQL 18 (docker-compose, porta 127.0.0.1:5432)
- Redis 7 (docker-compose, porta 127.0.0.1:6379)
- Secrets gerados em
.env(POSTGRES_PASSWORD, REDIS_PASSWORD, JWT_SECRET, JWT_REFRESH_SECRET, ENCRYPTION_KEY, ESL_PASSWORD) FREESWITCH_PATconfigurado em.env(não commitado)- FreeSWITCH (imagem própria via pacotes SignalWire, não compilada da fonte — ver docs/FREESWITCH.md; rodando, saudável, ~44MB RAM, senha ESL customizada, nenhuma porta exposta ao host)
- nginx (reverse proxy)
PHASE 05 — FreeSWITCH (agente.md secao 232)
- Imagem própria (
infrastructure/freeswitch/), pacotes SignalWire (PAT via BuildKit secret, nunca na imagem final — verificado comdocker history) - Módulos mínimos carregados: sofia, event_socket, commands, dptools, callcenter, avmd, curl, local_stream, etc. (mod_xml_curl instalado mas desativado até existir b2bcall-fs-config)
- Senha do Event Socket trocada da padrão via entrypoint runtime (nunca fica na imagem); porta 8021 não publicada no host
- docs/FREESWITCH.md, docs/NETWORK_ARCHITECTURE.md (decisão de network_mode adiada pra quando existir tronco SIP real)
- Diretório/dialplan ainda são os estáticos da config vanilla (ramais de teste 1000-1019, senhas fracas) — substituir por mod_xml_curl na fase Extensions/Trunks/Dialplan
PHASE 02 — SaaS Core
- Monorepo Node.js/TypeScript (pnpm workspaces, tsconfig base)
- Node 22 LTS + pnpm instalados no host
packages/database(Prisma 7 + driver adapterpg, migration inicial)packages/types(TenantStatus, AgentState),packages/shared- Tabela
tenantscriada via migration (seção 29 do agente.md)
PHASE 03 — Tenant Isolation
- Tabelas
users+tenant_memberships(tenant-scoped) - RLS (
ENABLE/FORCE ROW LEVEL SECURITY+ policy) emtenant_memberships - Tenant context via
set_config('app.current_tenant_id', ..., true)(transaction-local) - Helper
withTenantContext()empackages/database - Role de banco separado para runtime (
b2bcall_app, sem SUPERUSER/BYPASSRLS) — achado crítico: o role padrão do Docker Postgres é SUPERUSER e SEMPRE ignora RLS, até com FORCE. Verdocs/TENANT_ISOLATION.md. - Teste automatizado de isolamento (
pnpm --filter @b2bcall/database run test:isolation)
PHASE 04 — Authentication / RBAC
packages/auth: hash Argon2id (@node-rs/argon2), JWT access token (jose), refresh token opaco com rotation- Tabelas
roles,permissions,role_permissions,user_roles,sessions,audit_logs login()/refreshSession()/logout()/listUserTenants()/setActiveTenant()userHasPermission()(RBAC com scope PLATFORM/TENANT)- Seed: catálogo de permissions + roles de sistema + Platform Super Admin inicial
(senha em
FIRST_LOGIN.txt, fora do Git,mustChangePassword=true) - Teste automatizado (
pnpm --filter @b2bcall/auth run test:auth) apps/api(NestJS + Fastify): endpoints de auth, JwtAuthGuard, DomainExceptionFilter, rate limit de login via Redis (5/min por IP e por e-mail), helmet/cors, health checks — testado ponta a ponta com curl (login, refresh rotation, logout, RBAC, 401/403/429)- Password reset por e-mail — depende de SMTP configurado
PHASE 06+ — ver agente.md seções 21 em diante (Event Socket, XML Curl, Telefonia,
Call Center, Predictive Dialer, Recordings, AI, Billing, Frontend, Reports, Security, Tests)
Riscos conhecidos
- RAM da VM (1.9GB total): medido com Postgres+Redis+FreeSWITCH rodando juntos — ~91MB no total (Postgres 37MB, Redis 10MB, FreeSWITCH 44MB), bem tranquilo. O risco real ainda não testado é o build/runtime do Next.js (frontend) e vários workers Node simultâneos — reavaliar quando chegarmos lá.
- Disco (26GB livre): build do FreeSWITCH + imagens Docker + gravações vão consumir
espaço rápido. Monitorar com
df -h.