Arquitetura

Banco de Dados

Arquitetura de banco de dados dual - PostgreSQL e MySQL com Prisma 7.

Banco de Dados

O stCall utiliza uma arquitetura dual de banco de dados para separar dados da aplicação da configuração do PBX.

Visão Geral

BancoTipoPropósitoAcesso
PostgreSQLContainerizadoDados da aplicação stCallPrisma + @prisma/adapter-pg
MySQL (FreePBX)RemotoSincronização PJSIPPrisma + @prisma/adapter-mariadb
MySQL (CDR)RemotoRegistros de chamadasPrisma + @prisma/adapter-mariadb

PostgreSQL (Dados da Aplicação)

Configuração

  • Versão: PostgreSQL 16
  • Container: stcall-postgres
  • Schema: stcall
  • Porta: 5432

Tabelas

TabelaDescrição
usersContas de agentes/admins com senhas SIP criptografadas
callsRegistros de chamadas (similar a CDR)
call_eventsEventos ARI detalhados por chamada
agent_sessionsSessões de conexão WebSocket
agent_availabilityHistórico de mudanças de status dos agentes

Conexão via Prisma

import { PrismaClient } from '../../node_modules/.prisma/client-stcall/index.js'
import { PrismaPg } from '@prisma/adapter-pg'
import pg from 'pg'

const connectionString = `postgresql://${user}:${password}@${host}:${port}/${database}?schema=stcall`
const pool = new pg.Pool({ connectionString })
const adapter = new PrismaPg(pool)
const prisma = new PrismaClient({ adapter })

Schema Prisma

Arquivo: websockets-stcall/prisma/schema-stcall.prisma

datasource db {
  provider = "postgresql"
  schemas  = ["stcall"]
  // URL configurada no prisma.config.ts
}

MySQL (FreePBX)

Propósito

Sincronizar endpoints PJSIP WebRTC com o banco de dados do FreePBX.

Tabelas Utilizadas

TabelaDescrição
ps_endpointsConfiguração de endpoints PJSIP (WebRTC settings)
ps_authsCredenciais de autenticação (MD5 digest)
ps_aorsAddress of Record (configurações de registro)

Conexão via Prisma

import { PrismaClient } from '../../node_modules/.prisma/client-freepbx/index.js'
import { PrismaMariaDB } from '@prisma/adapter-mariadb'
import mariadb from 'mariadb'

const pool = mariadb.createPool({
  host, port, user, password, database,
  connectionLimit: 5,
})
const adapter = new PrismaMariaDB(pool)
const prisma = new PrismaClient({ adapter })
Nunca execute migrações no banco do FreePBX. Use db push apenas para validação de schema. O banco é gerenciado pelo FreePBX.

Prisma 7 - Padrão de Adaptadores

O Prisma ORM v7 introduziu uma mudança importante: o PrismaClient requer um adapter no construtor.

Configuração

Schema (SEM url):

datasource db {
  provider = "postgresql"
  schemas  = ["stcall"]
  // NÃO adicione url aqui no Prisma 7
}

Config (COM url):

// prisma.config.ts
import { defineConfig, env } from 'prisma/config'

export default defineConfig({
  schema: 'prisma/schema-stcall.prisma',
  migrations: {
    path: 'prisma/migrations-stcall',
  },
  datasource: {
    url: env('DATABASE_URL'),
  },
})

Estrutura de Arquivos

websockets-stcall/
├── prisma/
│   ├── schema.prisma              # MySQL (FreePBX)
│   ├── schema-stcall.prisma       # PostgreSQL (stCall)
│   ├── schema-cdr.prisma          # MySQL (CDR)
│   ├── migrations-freepbx/
│   └── migrations-stcall/
├── prisma.config.ts               # Config PostgreSQL (default)
└── prisma-freepbx.config.ts       # Config MySQL

Comandos Prisma

# Gerar clientes (sem config necessário)
bunx prisma generate --schema=./prisma/schema.prisma
bunx prisma generate --schema=./prisma/schema-stcall.prisma

# Migrações (REQUER config)
bunx prisma migrate deploy --config=./prisma.config.ts
bunx prisma migrate dev --name nome_da_migracao --config=./prisma.config.ts

# FreePBX (NUNCA migrar, usar db push)
bunx prisma db push --config=./prisma-freepbx.config.ts

Clientes Gerados

Os clientes Prisma são gerados durante o build do Docker:

RUN bunx prisma generate --schema=./prisma/schema.prisma
RUN bunx prisma generate --schema=./prisma/schema-stcall.prisma

Saída:

  • node_modules/.prisma/client-freepbx/ - Cliente MySQL
  • node_modules/.prisma/client-stcall/ - Cliente PostgreSQL

Pool de Conexões

BancoPool SizeMotivo
PostgreSQL10 (default)Aplicação principal, mais writes
MariaDB (FreePBX)5Leitura pesada, pouco write

Segurança

  • PostgreSQL: Restringir acesso à rede do container. Não expor ao público.
  • MySQL (FreePBX): Usar credenciais read-only quando possível. Usar SSH/VPN para acesso remoto.
  • Senhas SIP: Criptografadas no campo users.sipPassword com SIP_ENCRYPTION_KEY.
  • PJSIP: Autenticação MD5 digest (sem transmissão em texto plano).
Copyright © 2026