Files
App-Estoque-LiberiKids/sql/supabase-setup.sql
2025-11-29 21:31:52 -03:00

345 lines
15 KiB
PL/PgSQL

-- =============================================
-- CONFIGURAÇÃO COMPLETA DO SUPABASE
-- Sistema de Estoque Liberi Kids
-- =============================================
-- Habilitar extensões necessárias
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- =============================================
-- 1. TABELA DE CLIENTES
-- =============================================
CREATE TABLE IF NOT EXISTS clientes (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
nome_completo VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE,
whatsapp VARCHAR(20) NOT NULL UNIQUE, -- Login será por WhatsApp
telefone VARCHAR(20),
endereco TEXT,
cidade VARCHAR(100),
estado VARCHAR(50),
cep VARCHAR(10),
data_nascimento DATE,
observacoes TEXT,
ativo BOOLEAN DEFAULT true,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- =============================================
-- 2. TABELA DE FORNECEDORES
-- =============================================
CREATE TABLE IF NOT EXISTS fornecedores (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
nome VARCHAR(255) NOT NULL,
cnpj VARCHAR(18),
email VARCHAR(255),
telefone VARCHAR(20),
endereco TEXT,
cidade VARCHAR(100),
estado VARCHAR(50),
cep VARCHAR(10),
observacoes TEXT,
ativo BOOLEAN DEFAULT true,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- =============================================
-- 3. TABELA DE PRODUTOS
-- =============================================
CREATE TABLE IF NOT EXISTS produtos (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
id_produto VARCHAR(50) UNIQUE, -- Código do produto
marca VARCHAR(100) NOT NULL,
nome VARCHAR(255) NOT NULL,
descricao TEXT,
estacao VARCHAR(50) CHECK (estacao IN ('Verão', 'Inverno', 'Meia Estação')),
genero VARCHAR(20) CHECK (genero IN ('Masculino', 'Feminino', 'Unissex')),
fornecedor_id UUID REFERENCES fornecedores(id),
valor_compra DECIMAL(10,2),
valor_revenda DECIMAL(10,2),
foto_principal TEXT, -- URL da foto principal
ativo BOOLEAN DEFAULT true,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- =============================================
-- 4. TABELA DE VARIAÇÕES DE PRODUTOS
-- =============================================
CREATE TABLE IF NOT EXISTS produto_variacoes (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
produto_id UUID NOT NULL REFERENCES produtos(id) ON DELETE CASCADE,
tamanho VARCHAR(10) NOT NULL,
cor VARCHAR(50) NOT NULL,
quantidade INTEGER NOT NULL DEFAULT 0,
fotos TEXT[], -- Array de URLs das fotos
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
UNIQUE(produto_id, tamanho, cor)
);
-- =============================================
-- 5. TABELA DE VENDAS
-- =============================================
CREATE TABLE IF NOT EXISTS vendas (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
id_venda VARCHAR(50) UNIQUE, -- Código da venda
cliente_id UUID REFERENCES clientes(id),
tipo_pagamento VARCHAR(20) CHECK (tipo_pagamento IN ('vista', 'parcelado', 'prazo')),
valor_total DECIMAL(10,2) NOT NULL,
desconto DECIMAL(10,2) DEFAULT 0,
parcelas INTEGER DEFAULT 1,
valor_parcela DECIMAL(10,2),
data_venda DATE NOT NULL,
data_primeiro_vencimento DATE,
observacoes TEXT,
status VARCHAR(20) DEFAULT 'concluida' CHECK (status IN ('concluida', 'cancelada', 'pendente')),
origem VARCHAR(20) DEFAULT 'loja' CHECK (origem IN ('loja', 'catalogo')), -- Nova coluna para origem
eh_troca_devolucao BOOLEAN DEFAULT false, -- Para identificar trocas/devoluções
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- =============================================
-- 6. TABELA DE ITENS DA VENDA
-- =============================================
CREATE TABLE IF NOT EXISTS venda_itens (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
venda_id UUID NOT NULL REFERENCES vendas(id) ON DELETE CASCADE,
produto_id UUID NOT NULL REFERENCES produtos(id),
produto_variacao_id UUID NOT NULL REFERENCES produto_variacoes(id),
quantidade INTEGER NOT NULL,
valor_unitario DECIMAL(10,2) NOT NULL,
valor_total DECIMAL(10,2) NOT NULL,
status_item VARCHAR(20) DEFAULT 'vendido' CHECK (status_item IN ('vendido', 'trocado', 'devolvido')),
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- =============================================
-- 7. TABELA DE PARCELAS
-- =============================================
CREATE TABLE IF NOT EXISTS parcelas (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
venda_id UUID NOT NULL REFERENCES vendas(id) ON DELETE CASCADE,
numero_parcela INTEGER NOT NULL,
valor DECIMAL(10,2) NOT NULL,
data_vencimento DATE NOT NULL,
data_pagamento DATE,
status VARCHAR(20) DEFAULT 'pendente' CHECK (status IN ('pendente', 'paga', 'vencida')),
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- =============================================
-- 8. TABELA DE DEVOLUÇÕES/TROCAS
-- =============================================
CREATE TABLE IF NOT EXISTS devolucoes (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
venda_id UUID NOT NULL REFERENCES vendas(id) ON DELETE CASCADE,
item_id UUID NOT NULL REFERENCES venda_itens(id) ON DELETE CASCADE,
quantidade_devolvida INTEGER NOT NULL CHECK (quantidade_devolvida > 0),
valor_devolucao DECIMAL(10,2) NOT NULL CHECK (valor_devolucao >= 0),
tipo_operacao VARCHAR(20) DEFAULT 'devolucao' CHECK (tipo_operacao IN ('devolucao', 'troca')),
motivo TEXT,
data_devolucao DATE NOT NULL DEFAULT CURRENT_DATE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- =============================================
-- 9. TABELA DE DESPESAS
-- =============================================
CREATE TABLE IF NOT EXISTS despesas (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
tipo_despesa_id UUID REFERENCES tipos_despesa(id),
descricao VARCHAR(255) NOT NULL,
valor DECIMAL(10,2) NOT NULL,
data_despesa DATE NOT NULL,
observacoes TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- =============================================
-- 10. TABELA DE TIPOS DE DESPESA
-- =============================================
CREATE TABLE IF NOT EXISTS tipos_despesa (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
nome VARCHAR(100) NOT NULL UNIQUE,
descricao TEXT,
ativo BOOLEAN DEFAULT true,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- =============================================
-- 11. TABELA DE PEDIDOS DO CATÁLOGO
-- =============================================
CREATE TABLE IF NOT EXISTS pedidos_catalogo (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
cliente_id UUID NOT NULL REFERENCES clientes(id),
status VARCHAR(20) DEFAULT 'pendente' CHECK (status IN ('pendente', 'processando', 'concluido', 'cancelado')),
valor_total DECIMAL(10,2) NOT NULL,
observacoes TEXT,
data_pedido TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
data_processamento TIMESTAMP WITH TIME ZONE,
venda_id UUID REFERENCES vendas(id), -- Referência para a venda criada no app
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- =============================================
-- 12. TABELA DE ITENS DO PEDIDO CATÁLOGO
-- =============================================
CREATE TABLE IF NOT EXISTS pedido_catalogo_itens (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
pedido_id UUID NOT NULL REFERENCES pedidos_catalogo(id) ON DELETE CASCADE,
produto_id UUID NOT NULL REFERENCES produtos(id),
produto_variacao_id UUID NOT NULL REFERENCES produto_variacoes(id),
quantidade INTEGER NOT NULL,
valor_unitario DECIMAL(10,2) NOT NULL,
valor_total DECIMAL(10,2) NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- =============================================
-- 13. TABELA DE CONFIGURAÇÕES
-- =============================================
CREATE TABLE IF NOT EXISTS configuracoes (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
chave VARCHAR(100) NOT NULL UNIQUE,
valor TEXT,
tipo VARCHAR(50) DEFAULT 'string',
descricao TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- =============================================
-- ÍNDICES PARA PERFORMANCE
-- =============================================
-- Clientes
CREATE INDEX IF NOT EXISTS idx_clientes_whatsapp ON clientes(whatsapp);
CREATE INDEX IF NOT EXISTS idx_clientes_email ON clientes(email);
-- Produtos
CREATE INDEX IF NOT EXISTS idx_produtos_marca ON produtos(marca);
CREATE INDEX IF NOT EXISTS idx_produtos_nome ON produtos(nome);
CREATE INDEX IF NOT EXISTS idx_produtos_ativo ON produtos(ativo);
-- Variações
CREATE INDEX IF NOT EXISTS idx_variacoes_produto ON produto_variacoes(produto_id);
CREATE INDEX IF NOT EXISTS idx_variacoes_estoque ON produto_variacoes(quantidade);
-- Vendas
CREATE INDEX IF NOT EXISTS idx_vendas_cliente ON vendas(cliente_id);
CREATE INDEX IF NOT EXISTS idx_vendas_data ON vendas(data_venda);
CREATE INDEX IF NOT EXISTS idx_vendas_status ON vendas(status);
CREATE INDEX IF NOT EXISTS idx_vendas_origem ON vendas(origem);
-- Itens da venda
CREATE INDEX IF NOT EXISTS idx_venda_itens_venda ON venda_itens(venda_id);
CREATE INDEX IF NOT EXISTS idx_venda_itens_produto ON venda_itens(produto_id);
-- Parcelas
CREATE INDEX IF NOT EXISTS idx_parcelas_venda ON parcelas(venda_id);
CREATE INDEX IF NOT EXISTS idx_parcelas_vencimento ON parcelas(data_vencimento);
CREATE INDEX IF NOT EXISTS idx_parcelas_status ON parcelas(status);
-- Pedidos catálogo
CREATE INDEX IF NOT EXISTS idx_pedidos_cliente ON pedidos_catalogo(cliente_id);
CREATE INDEX IF NOT EXISTS idx_pedidos_status ON pedidos_catalogo(status);
CREATE INDEX IF NOT EXISTS idx_pedidos_data ON pedidos_catalogo(data_pedido);
-- =============================================
-- TRIGGERS PARA UPDATED_AT
-- =============================================
-- Função para atualizar updated_at
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ language 'plpgsql';
-- Aplicar trigger em todas as tabelas relevantes
CREATE TRIGGER update_clientes_updated_at BEFORE UPDATE ON clientes FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_fornecedores_updated_at BEFORE UPDATE ON fornecedores FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_produtos_updated_at BEFORE UPDATE ON produtos FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_produto_variacoes_updated_at BEFORE UPDATE ON produto_variacoes FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_vendas_updated_at BEFORE UPDATE ON vendas FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_parcelas_updated_at BEFORE UPDATE ON parcelas FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_devolucoes_updated_at BEFORE UPDATE ON devolucoes FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_despesas_updated_at BEFORE UPDATE ON despesas FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_tipos_despesa_updated_at BEFORE UPDATE ON tipos_despesa FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_pedidos_catalogo_updated_at BEFORE UPDATE ON pedidos_catalogo FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_configuracoes_updated_at BEFORE UPDATE ON configuracoes FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
-- =============================================
-- INSERIR DADOS INICIAIS
-- =============================================
-- Tipos de despesa padrão
INSERT INTO tipos_despesa (nome, descricao) VALUES
('Aluguel', 'Despesas com aluguel do estabelecimento'),
('Energia Elétrica', 'Conta de luz'),
('Água', 'Conta de água'),
('Internet', 'Serviços de internet e telefonia'),
('Marketing', 'Gastos com publicidade e marketing'),
('Transporte', 'Combustível, manutenção de veículos'),
('Materiais', 'Materiais de escritório e limpeza'),
('Outros', 'Outras despesas diversas')
ON CONFLICT (nome) DO NOTHING;
-- Configurações padrão do sistema
INSERT INTO configuracoes (chave, valor, tipo, descricao) VALUES
('sistema_nome', 'Liberi Kids', 'string', 'Nome do sistema'),
('catalogo_ativo', 'true', 'boolean', 'Se o catálogo online está ativo'),
('whatsapp_alertas', 'false', 'boolean', 'Se os alertas por WhatsApp estão ativos'),
('chatgpt_ativo', 'false', 'boolean', 'Se a integração com ChatGPT está ativa'),
('evolution_api_ativo', 'false', 'boolean', 'Se a Evolution API está ativa')
ON CONFLICT (chave) DO NOTHING;
-- =============================================
-- POLÍTICAS DE SEGURANÇA (RLS)
-- =============================================
-- Habilitar RLS nas tabelas principais
ALTER TABLE clientes ENABLE ROW LEVEL SECURITY;
ALTER TABLE produtos ENABLE ROW LEVEL SECURITY;
ALTER TABLE produto_variacoes ENABLE ROW LEVEL SECURITY;
ALTER TABLE vendas ENABLE ROW LEVEL SECURITY;
ALTER TABLE pedidos_catalogo ENABLE ROW LEVEL SECURITY;
-- Política para permitir leitura pública de produtos (para o catálogo)
CREATE POLICY "Produtos são visíveis publicamente" ON produtos FOR SELECT USING (ativo = true);
CREATE POLICY "Variações são visíveis publicamente" ON produto_variacoes FOR SELECT USING (true);
-- Política para clientes (podem ver apenas seus próprios dados)
CREATE POLICY "Clientes podem ver seus próprios dados" ON clientes FOR SELECT USING (auth.uid()::text = id::text);
CREATE POLICY "Clientes podem atualizar seus próprios dados" ON clientes FOR UPDATE USING (auth.uid()::text = id::text);
-- Política para pedidos (clientes podem ver apenas seus próprios pedidos)
CREATE POLICY "Clientes podem ver seus próprios pedidos" ON pedidos_catalogo FOR SELECT USING (auth.uid()::text = cliente_id::text);
CREATE POLICY "Clientes podem criar pedidos" ON pedidos_catalogo FOR INSERT WITH CHECK (auth.uid()::text = cliente_id::text);
-- =============================================
-- COMENTÁRIOS PARA DOCUMENTAÇÃO
-- =============================================
COMMENT ON TABLE clientes IS 'Cadastro de clientes da loja e do catálogo online';
COMMENT ON TABLE produtos IS 'Catálogo de produtos com informações básicas';
COMMENT ON TABLE produto_variacoes IS 'Variações dos produtos (tamanho, cor, estoque)';
COMMENT ON TABLE vendas IS 'Registro de todas as vendas (loja física e catálogo)';
COMMENT ON TABLE pedidos_catalogo IS 'Pedidos realizados através do catálogo online';
COMMENT ON TABLE configuracoes IS 'Configurações gerais do sistema';
COMMENT ON COLUMN vendas.origem IS 'Origem da venda: loja (física) ou catalogo (online)';
COMMENT ON COLUMN clientes.whatsapp IS 'Número do WhatsApp usado para login no catálogo';
COMMENT ON COLUMN pedidos_catalogo.venda_id IS 'ID da venda criada no app após processar o pedido';