452 lines
19 KiB
SQL
452 lines
19 KiB
SQL
-- ============================================================
|
|
-- SeConectAI Vendas — Schema PostgreSQL (multi-tenant CRM/Vendas)
|
|
-- ============================================================
|
|
-- Estratégia de multi-tenancy: banco único, isolado por tenant_id
|
|
-- + Row Level Security (RLS). Mais simples de operar em Docker/
|
|
-- Docker Compose do que "schema por tenant" e escala bem até
|
|
-- centenas de tenants num único Postgres.
|
|
-- ============================================================
|
|
|
|
CREATE EXTENSION IF NOT EXISTS "pgcrypto"; -- gen_random_uuid()
|
|
|
|
-- ============================================================
|
|
-- 1. NÍVEL MASTER (você — dono da plataforma)
|
|
-- ============================================================
|
|
|
|
CREATE TABLE master_admins (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
nome VARCHAR(150) NOT NULL,
|
|
email VARCHAR(150) UNIQUE NOT NULL,
|
|
senha_hash TEXT NOT NULL, -- argon2id ou bcrypt cost>=12
|
|
ativo BOOLEAN NOT NULL DEFAULT TRUE,
|
|
mfa_secret TEXT, -- TOTP opcional, recomendado p/ master
|
|
ultimo_login TIMESTAMPTZ,
|
|
criado_em TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
atualizado_em TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
-- Conexão(ões) com a Evolution API 2.3, cadastrada pelo master.
|
|
-- Pode haver mais de um servidor Evolution (ex: para balancear carga).
|
|
CREATE TABLE evolution_api_config (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
nome VARCHAR(100) NOT NULL, -- "Servidor Principal"
|
|
base_url VARCHAR(255) NOT NULL,
|
|
api_key_cripto TEXT NOT NULL, -- criptografar em repouso (app-level, ex: AES-256-GCM)
|
|
versao VARCHAR(20) NOT NULL DEFAULT '2.3',
|
|
ativo BOOLEAN NOT NULL DEFAULT TRUE,
|
|
criado_em TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
-- Config SMTP padrão da plataforma (fallback quando o tenant não
|
|
-- tem SMTP próprio cadastrado)
|
|
CREATE TABLE master_email_config (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
smtp_host VARCHAR(150) NOT NULL,
|
|
smtp_porta INTEGER NOT NULL,
|
|
smtp_usuario VARCHAR(150) NOT NULL,
|
|
smtp_senha_cripto TEXT NOT NULL,
|
|
email_remetente VARCHAR(150) NOT NULL,
|
|
ativo BOOLEAN NOT NULL DEFAULT TRUE,
|
|
criado_em TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE TABLE planos (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
nome VARCHAR(100) NOT NULL,
|
|
descricao TEXT,
|
|
valor_mensal NUMERIC(10,2) NOT NULL,
|
|
limite_customers INTEGER, -- NULL = ilimitado
|
|
limite_usuarios INTEGER,
|
|
limite_instancias_whatsapp INTEGER NOT NULL DEFAULT 1,
|
|
ativo BOOLEAN NOT NULL DEFAULT TRUE,
|
|
criado_em TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- 2. TENANTS — seus clientes que compram/usam a plataforma
|
|
-- ============================================================
|
|
|
|
CREATE TYPE tenant_status AS ENUM ('trial', 'ativo', 'inadimplente', 'suspenso', 'cancelado');
|
|
|
|
CREATE TABLE tenants (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
razao_social VARCHAR(200) NOT NULL,
|
|
nome_fantasia VARCHAR(200),
|
|
documento VARCHAR(20), -- CNPJ/CPF
|
|
email_contato VARCHAR(150) NOT NULL,
|
|
telefone VARCHAR(20),
|
|
logo_url TEXT, -- personalização visual (whitelabel)
|
|
cor_primaria VARCHAR(7), -- "#1a73e8"
|
|
plano_id UUID REFERENCES planos(id),
|
|
status tenant_status NOT NULL DEFAULT 'trial',
|
|
dia_vencimento_mensalidade SMALLINT NOT NULL DEFAULT 10
|
|
CHECK (dia_vencimento_mensalidade BETWEEN 1 AND 28),
|
|
trial_expira_em TIMESTAMPTZ,
|
|
criado_por UUID REFERENCES master_admins(id),
|
|
criado_em TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
atualizado_em TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX idx_tenants_status ON tenants(status);
|
|
|
|
-- Faturas da mensalidade (você cobrando o tenant)
|
|
CREATE TYPE cobranca_status AS ENUM ('pendente', 'pago', 'atrasado', 'cancelado');
|
|
|
|
CREATE TABLE tenant_faturas (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
|
referencia VARCHAR(7) NOT NULL, -- '2026-08'
|
|
valor NUMERIC(10,2) NOT NULL,
|
|
vencimento DATE NOT NULL,
|
|
pago_em TIMESTAMPTZ,
|
|
status cobranca_status NOT NULL DEFAULT 'pendente',
|
|
alerta_enviado_em TIMESTAMPTZ,
|
|
criado_em TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
UNIQUE(tenant_id, referencia)
|
|
);
|
|
|
|
CREATE INDEX idx_tenant_faturas_venc
|
|
ON tenant_faturas(vencimento) WHERE status IN ('pendente', 'atrasado');
|
|
|
|
-- ============================================================
|
|
-- 3. USUÁRIOS E AUTENTICAÇÃO
|
|
-- ============================================================
|
|
|
|
CREATE TYPE user_role AS ENUM ('tenant_admin', 'vendedor', 'financeiro', 'visualizador');
|
|
|
|
CREATE TABLE tenant_users (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
|
nome VARCHAR(150) NOT NULL,
|
|
email VARCHAR(150) NOT NULL,
|
|
senha_hash TEXT NOT NULL,
|
|
role user_role NOT NULL DEFAULT 'vendedor',
|
|
ativo BOOLEAN NOT NULL DEFAULT TRUE,
|
|
mfa_secret TEXT,
|
|
ultimo_login TIMESTAMPTZ,
|
|
criado_em TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
UNIQUE(tenant_id, email)
|
|
);
|
|
|
|
CREATE INDEX idx_tenant_users_tenant ON tenant_users(tenant_id);
|
|
|
|
-- Refresh tokens (JWT access token curto + refresh token com rotação)
|
|
CREATE TABLE auth_refresh_tokens (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
usuario_tipo VARCHAR(20) NOT NULL, -- 'master' | 'tenant_user'
|
|
usuario_id UUID NOT NULL,
|
|
token_hash TEXT NOT NULL, -- nunca guardar o token em texto puro
|
|
expira_em TIMESTAMPTZ NOT NULL,
|
|
revogado BOOLEAN NOT NULL DEFAULT FALSE,
|
|
ip_origem INET,
|
|
user_agent TEXT,
|
|
criado_em TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX idx_refresh_tokens_usuario ON auth_refresh_tokens(usuario_tipo, usuario_id);
|
|
|
|
CREATE TABLE password_reset_tokens (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
usuario_tipo VARCHAR(20) NOT NULL,
|
|
usuario_id UUID NOT NULL,
|
|
token_hash TEXT NOT NULL,
|
|
expira_em TIMESTAMPTZ NOT NULL,
|
|
usado BOOLEAN NOT NULL DEFAULT FALSE,
|
|
criado_em TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
-- Registro de tentativas de login (para rate-limit/bloqueio de força bruta)
|
|
CREATE TABLE login_attempts (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
email VARCHAR(150) NOT NULL,
|
|
usuario_tipo VARCHAR(20) NOT NULL,
|
|
sucesso BOOLEAN NOT NULL,
|
|
ip_origem INET,
|
|
criado_em TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX idx_login_attempts_email_data ON login_attempts(email, criado_em);
|
|
|
|
-- ============================================================
|
|
-- 4. INTEGRAÇÕES POR TENANT (WhatsApp / E-mail / Templates)
|
|
-- ============================================================
|
|
|
|
CREATE TABLE tenant_whatsapp_instances (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
|
evolution_config_id UUID REFERENCES evolution_api_config(id),
|
|
instance_name VARCHAR(100) NOT NULL UNIQUE, -- nome único na Evolution API
|
|
numero_conectado VARCHAR(20),
|
|
status VARCHAR(30) NOT NULL DEFAULT 'desconectado',
|
|
-- desconectado | conectando | conectado | erro
|
|
qr_code_gerado_em TIMESTAMPTZ,
|
|
criado_em TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE TABLE tenant_email_config (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL UNIQUE REFERENCES tenants(id) ON DELETE CASCADE,
|
|
smtp_host VARCHAR(150),
|
|
smtp_porta INTEGER,
|
|
smtp_usuario VARCHAR(150),
|
|
smtp_senha_cripto TEXT,
|
|
email_remetente VARCHAR(150),
|
|
usar_config_padrao BOOLEAN NOT NULL DEFAULT TRUE, -- usa master_email_config se true
|
|
criado_em TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
-- Templates de mensagens (nível master = padrão global; nível tenant = customizado)
|
|
CREATE TABLE alert_templates (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE, -- NULL = template padrão da plataforma
|
|
tipo VARCHAR(50) NOT NULL,
|
|
-- 'mensalidade_tenant' | 'cobranca_cliente' | 'venda_confirmada' | 'lembrete_vencimento'
|
|
canal VARCHAR(20) NOT NULL, -- 'whatsapp' | 'email'
|
|
assunto VARCHAR(200), -- só para email
|
|
corpo TEXT NOT NULL, -- placeholders: {{nome}}, {{valor}}, {{vencimento}}
|
|
ativo BOOLEAN NOT NULL DEFAULT TRUE,
|
|
criado_em TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
-- Log/auditoria de todo alerta disparado (master->tenant e tenant->customer)
|
|
CREATE TABLE alert_logs (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
|
|
destinatario_tipo VARCHAR(20) NOT NULL, -- 'tenant' | 'customer'
|
|
destinatario_id UUID NOT NULL, -- id do tenant ou do customer
|
|
canal VARCHAR(20) NOT NULL, -- whatsapp | email
|
|
template_id UUID REFERENCES alert_templates(id),
|
|
conteudo_enviado TEXT,
|
|
status VARCHAR(20) NOT NULL DEFAULT 'enviado', -- enviado | falhou | entregue | lido
|
|
erro TEXT,
|
|
enviado_em TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX idx_alert_logs_tenant ON alert_logs(tenant_id, enviado_em);
|
|
|
|
-- ============================================================
|
|
-- 5. CLIENTES DO TENANT ("customers" — empresas atendidas)
|
|
-- ============================================================
|
|
|
|
CREATE TABLE customers (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
|
razao_social VARCHAR(200) NOT NULL,
|
|
nome_fantasia VARCHAR(200),
|
|
documento VARCHAR(20),
|
|
email VARCHAR(150),
|
|
telefone_whatsapp VARCHAR(20),
|
|
endereco TEXT,
|
|
cidade VARCHAR(100),
|
|
uf CHAR(2),
|
|
observacoes TEXT,
|
|
ativo BOOLEAN NOT NULL DEFAULT TRUE,
|
|
criado_em TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
atualizado_em TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX idx_customers_tenant ON customers(tenant_id);
|
|
|
|
CREATE TABLE customer_contacts (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
customer_id UUID NOT NULL REFERENCES customers(id) ON DELETE CASCADE,
|
|
nome VARCHAR(150) NOT NULL,
|
|
cargo VARCHAR(100),
|
|
email VARCHAR(150),
|
|
telefone_whatsapp VARCHAR(20),
|
|
principal BOOLEAN NOT NULL DEFAULT FALSE,
|
|
criado_em TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- 6. PRODUTOS E SERVIÇOS DO TENANT
|
|
-- ============================================================
|
|
|
|
CREATE TYPE item_tipo AS ENUM ('produto', 'servico');
|
|
|
|
CREATE TABLE products_services (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
|
tipo item_tipo NOT NULL,
|
|
nome VARCHAR(200) NOT NULL,
|
|
descricao TEXT,
|
|
sku VARCHAR(50),
|
|
valor_venda NUMERIC(12,2) NOT NULL,
|
|
valor_custo NUMERIC(12,2),
|
|
unidade VARCHAR(20) NOT NULL DEFAULT 'un', -- un, hora, mês...
|
|
recorrente BOOLEAN NOT NULL DEFAULT FALSE, -- ex: serviço de mensalidade
|
|
ativo BOOLEAN NOT NULL DEFAULT TRUE,
|
|
criado_em TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
atualizado_em TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
UNIQUE(tenant_id, sku)
|
|
);
|
|
|
|
CREATE INDEX idx_products_tenant ON products_services(tenant_id);
|
|
|
|
-- ============================================================
|
|
-- 7. VENDAS
|
|
-- ============================================================
|
|
|
|
CREATE TYPE venda_status AS ENUM ('orcamento', 'confirmada', 'cancelada', 'concluida');
|
|
|
|
CREATE TABLE sales (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
|
customer_id UUID NOT NULL REFERENCES customers(id),
|
|
vendedor_id UUID REFERENCES tenant_users(id),
|
|
numero_venda SERIAL,
|
|
status venda_status NOT NULL DEFAULT 'confirmada',
|
|
valor_total NUMERIC(12,2) NOT NULL DEFAULT 0,
|
|
desconto NUMERIC(12,2) NOT NULL DEFAULT 0,
|
|
observacoes TEXT,
|
|
data_venda DATE NOT NULL DEFAULT CURRENT_DATE,
|
|
criado_em TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
atualizado_em TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX idx_sales_tenant_data ON sales(tenant_id, data_venda);
|
|
CREATE INDEX idx_sales_customer ON sales(customer_id);
|
|
|
|
CREATE TABLE sale_items (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
sale_id UUID NOT NULL REFERENCES sales(id) ON DELETE CASCADE,
|
|
product_service_id UUID NOT NULL REFERENCES products_services(id),
|
|
quantidade NUMERIC(10,2) NOT NULL DEFAULT 1,
|
|
valor_unitario NUMERIC(12,2) NOT NULL,
|
|
valor_total NUMERIC(12,2) NOT NULL
|
|
);
|
|
|
|
CREATE INDEX idx_sale_items_sale ON sale_items(sale_id);
|
|
|
|
-- Parcelas/recebimentos: contas a receber do tenant junto ao customer
|
|
CREATE TYPE parcela_status AS ENUM ('pendente', 'pago', 'atrasado', 'cancelado');
|
|
|
|
CREATE TABLE sale_payments (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
sale_id UUID NOT NULL REFERENCES sales(id) ON DELETE CASCADE,
|
|
numero_parcela SMALLINT NOT NULL DEFAULT 1,
|
|
valor NUMERIC(12,2) NOT NULL,
|
|
vencimento DATE NOT NULL,
|
|
pago_em TIMESTAMPTZ,
|
|
forma_pagamento VARCHAR(30), -- pix, boleto, cartao, dinheiro
|
|
status parcela_status NOT NULL DEFAULT 'pendente',
|
|
alerta_enviado_em TIMESTAMPTZ,
|
|
criado_em TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX idx_sale_payments_venc
|
|
ON sale_payments(vencimento) WHERE status IN ('pendente', 'atrasado');
|
|
|
|
-- ============================================================
|
|
-- 8. AUDITORIA GERAL
|
|
-- ============================================================
|
|
|
|
CREATE TABLE audit_logs (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID REFERENCES tenants(id) ON DELETE SET NULL,
|
|
usuario_tipo VARCHAR(20) NOT NULL, -- master | tenant_user
|
|
usuario_id UUID,
|
|
acao VARCHAR(100) NOT NULL, -- login, criar_venda, excluir_cliente...
|
|
entidade VARCHAR(50),
|
|
entidade_id UUID,
|
|
detalhes JSONB,
|
|
ip_origem INET,
|
|
criado_em TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX idx_audit_tenant_data ON audit_logs(tenant_id, criado_em);
|
|
|
|
-- ============================================================
|
|
-- 9. VIEWS DE DASHBOARD (usadas no painel do tenant)
|
|
-- ============================================================
|
|
|
|
CREATE VIEW vw_resumo_vendas_semanal AS
|
|
SELECT
|
|
s.tenant_id,
|
|
date_trunc('week', s.data_venda)::date AS semana,
|
|
COUNT(*) AS qtd_vendas,
|
|
SUM(s.valor_total) AS total_vendido
|
|
FROM sales s
|
|
WHERE s.status IN ('confirmada', 'concluida')
|
|
GROUP BY s.tenant_id, date_trunc('week', s.data_venda);
|
|
|
|
CREATE VIEW vw_resumo_vendas_mensal AS
|
|
SELECT
|
|
s.tenant_id,
|
|
date_trunc('month', s.data_venda)::date AS mes,
|
|
COUNT(*) AS qtd_vendas,
|
|
SUM(s.valor_total) AS total_vendido
|
|
FROM sales s
|
|
WHERE s.status IN ('confirmada', 'concluida')
|
|
GROUP BY s.tenant_id, date_trunc('month', s.data_venda);
|
|
|
|
CREATE VIEW vw_recebimentos AS
|
|
SELECT
|
|
sp.id,
|
|
s.tenant_id,
|
|
s.customer_id,
|
|
sp.valor,
|
|
sp.vencimento,
|
|
sp.status,
|
|
sp.pago_em
|
|
FROM sale_payments sp
|
|
JOIN sales s ON s.id = sp.sale_id;
|
|
|
|
-- ============================================================
|
|
-- 10. ROW LEVEL SECURITY — isolamento entre tenants
|
|
-- ============================================================
|
|
-- A aplicação deve definir, por conexão/transação:
|
|
-- SET app.current_tenant_id = '<uuid-do-tenant-logado>';
|
|
-- Usuários master (que enxergam todos os tenants) usam uma role
|
|
-- de banco separada (ex: app_master) que faz BYPASS RLS, ou uma
|
|
-- policy adicional que libera quando app.is_master = 'true'.
|
|
|
|
ALTER TABLE customers ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE customer_contacts ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE products_services ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE sales ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE sale_items ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE sale_payments ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE tenant_users ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE tenant_whatsapp_instances ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE tenant_email_config ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY tenant_isolation_customers ON customers
|
|
USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);
|
|
|
|
CREATE POLICY tenant_isolation_products ON products_services
|
|
USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);
|
|
|
|
CREATE POLICY tenant_isolation_sales ON sales
|
|
USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);
|
|
|
|
CREATE POLICY tenant_isolation_tenant_users ON tenant_users
|
|
USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);
|
|
|
|
CREATE POLICY tenant_isolation_whatsapp ON tenant_whatsapp_instances
|
|
USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);
|
|
|
|
CREATE POLICY tenant_isolation_email_config ON tenant_email_config
|
|
USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);
|
|
|
|
-- sale_items e customer_contacts não têm tenant_id direto: isolar via join
|
|
CREATE POLICY tenant_isolation_sale_items ON sale_items
|
|
USING (sale_id IN (
|
|
SELECT id FROM sales
|
|
WHERE tenant_id = current_setting('app.current_tenant_id', true)::uuid
|
|
));
|
|
|
|
CREATE POLICY tenant_isolation_sale_payments ON sale_payments
|
|
USING (sale_id IN (
|
|
SELECT id FROM sales
|
|
WHERE tenant_id = current_setting('app.current_tenant_id', true)::uuid
|
|
));
|
|
|
|
CREATE POLICY tenant_isolation_customer_contacts ON customer_contacts
|
|
USING (customer_id IN (
|
|
SELECT id FROM customers
|
|
WHERE tenant_id = current_setting('app.current_tenant_id', true)::uuid
|
|
));
|
|
|
|
-- Fim do schema
|