chore: sincroniza projeto para gitea
This commit is contained in:
58
sql/add-campos-catalogo-melhorias.sql
Normal file
58
sql/add-campos-catalogo-melhorias.sql
Normal file
@@ -0,0 +1,58 @@
|
||||
-- =============================================
|
||||
-- ADICIONAR CAMPOS PARA MELHORIAS DO CATÁLOGO
|
||||
-- Execute este script no SQL Editor do Supabase
|
||||
-- =============================================
|
||||
|
||||
-- 1. Adicionar campos na tabela produtos
|
||||
ALTER TABLE produtos
|
||||
ADD COLUMN IF NOT EXISTS preco_promocional DECIMAL(10,2),
|
||||
ADD COLUMN IF NOT EXISTS em_promocao BOOLEAN DEFAULT false,
|
||||
ADD COLUMN IF NOT EXISTS novidade BOOLEAN DEFAULT false;
|
||||
|
||||
-- 2. Criar índices para melhor performance
|
||||
CREATE INDEX IF NOT EXISTS idx_produtos_em_promocao ON produtos(em_promocao) WHERE em_promocao = true;
|
||||
CREATE INDEX IF NOT EXISTS idx_produtos_novidade ON produtos(novidade) WHERE novidade = true;
|
||||
CREATE INDEX IF NOT EXISTS idx_produtos_catalogo_flags ON produtos(visivel_catalogo, em_promocao, novidade) WHERE visivel_catalogo = true;
|
||||
|
||||
-- 3. Comentários para documentação
|
||||
COMMENT ON COLUMN produtos.preco_promocional IS 'Preço promocional do produto (se em promoção)';
|
||||
COMMENT ON COLUMN produtos.em_promocao IS 'Indica se o produto está em promoção';
|
||||
COMMENT ON COLUMN produtos.novidade IS 'Indica se o produto é novidade';
|
||||
|
||||
-- 4. Verificar estrutura
|
||||
SELECT
|
||||
column_name,
|
||||
data_type,
|
||||
is_nullable,
|
||||
column_default
|
||||
FROM information_schema.columns
|
||||
WHERE table_name = 'produtos'
|
||||
AND column_name IN ('preco_promocional', 'em_promocao', 'novidade')
|
||||
ORDER BY ordinal_position;
|
||||
|
||||
-- 5. Estatísticas iniciais
|
||||
SELECT
|
||||
'Produtos por categoria' as info,
|
||||
COUNT(*) FILTER (WHERE em_promocao = true) as "Em Promoção",
|
||||
COUNT(*) FILTER (WHERE novidade = true) as "Novidades",
|
||||
COUNT(*) FILTER (WHERE visivel_catalogo = true) as "Visíveis no Catálogo",
|
||||
COUNT(*) as "Total"
|
||||
FROM produtos;
|
||||
|
||||
-- =============================================
|
||||
-- SUCESSO!
|
||||
-- =============================================
|
||||
|
||||
/*
|
||||
✅ CAMPOS ADICIONADOS COM SUCESSO!
|
||||
|
||||
Novos campos disponíveis:
|
||||
- preco_promocional (DECIMAL): Preço em promoção
|
||||
- em_promocao (BOOLEAN): Flag de promoção
|
||||
- novidade (BOOLEAN): Flag de novidade
|
||||
|
||||
Próximos passos:
|
||||
1. Atualizar o painel admin para gerenciar esses campos
|
||||
2. Atualizar o site para exibir promoções e novidades
|
||||
3. Adicionar badges visuais para "PROMOÇÃO" e "NOVO"
|
||||
*/
|
||||
44
sql/add-catalogo-visibility.sql
Normal file
44
sql/add-catalogo-visibility.sql
Normal file
@@ -0,0 +1,44 @@
|
||||
-- =============================================
|
||||
-- ADICIONAR CAMPO DE VISIBILIDADE NO CATÁLOGO
|
||||
-- Execute este script no SQL Editor do Supabase
|
||||
-- =============================================
|
||||
|
||||
-- Adicionar coluna visivel_catalogo à tabela produtos
|
||||
ALTER TABLE produtos
|
||||
ADD COLUMN IF NOT EXISTS visivel_catalogo BOOLEAN DEFAULT true;
|
||||
|
||||
-- Criar índice para melhorar performance das consultas
|
||||
CREATE INDEX IF NOT EXISTS idx_produtos_visivel_catalogo
|
||||
ON produtos(visivel_catalogo);
|
||||
|
||||
-- Atualizar produtos existentes para serem visíveis por padrão
|
||||
UPDATE produtos
|
||||
SET visivel_catalogo = true
|
||||
WHERE visivel_catalogo IS NULL;
|
||||
|
||||
-- Verificar se foi adicionado corretamente
|
||||
SELECT
|
||||
'Produtos visíveis no catálogo:' as status,
|
||||
COUNT(*) as total
|
||||
FROM produtos
|
||||
WHERE visivel_catalogo = true;
|
||||
|
||||
SELECT
|
||||
'Produtos ocultos do catálogo:' as status,
|
||||
COUNT(*) as total
|
||||
FROM produtos
|
||||
WHERE visivel_catalogo = false;
|
||||
|
||||
-- =============================================
|
||||
-- INSTRUÇÕES
|
||||
-- =============================================
|
||||
|
||||
/*
|
||||
✅ CAMPO ADICIONADO COM SUCESSO!
|
||||
|
||||
O campo 'visivel_catalogo' foi adicionado à tabela produtos.
|
||||
Por padrão, todos os produtos existentes foram marcados como visíveis.
|
||||
|
||||
Você pode agora gerenciar a visibilidade dos produtos através do menu:
|
||||
Site / Catalogo
|
||||
*/
|
||||
39
sql/add-client-passwords.sql
Normal file
39
sql/add-client-passwords.sql
Normal file
@@ -0,0 +1,39 @@
|
||||
-- =============================================
|
||||
-- ADICIONAR SISTEMA DE SENHAS PARA CLIENTES
|
||||
-- =============================================
|
||||
|
||||
-- Adicionar coluna de senha na tabela clientes (opcional, para referência)
|
||||
ALTER TABLE clientes
|
||||
ADD COLUMN IF NOT EXISTS senha_hash VARCHAR(255);
|
||||
|
||||
-- Criar índice para melhor performance nas consultas de autenticação
|
||||
CREATE INDEX IF NOT EXISTS idx_clientes_whatsapp ON clientes(whatsapp);
|
||||
CREATE INDEX IF NOT EXISTS idx_clientes_email ON clientes(email);
|
||||
|
||||
-- Comentários para documentação
|
||||
COMMENT ON COLUMN clientes.senha_hash IS 'Hash da senha do cliente para autenticação no catálogo';
|
||||
|
||||
-- Habilitar RLS (Row Level Security) se ainda não estiver habilitado
|
||||
ALTER TABLE clientes ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- Remover políticas existentes se houver (para evitar conflitos)
|
||||
DROP POLICY IF EXISTS "Clientes podem ver apenas seus próprios dados" ON clientes;
|
||||
DROP POLICY IF EXISTS "Permitir inserção de novos clientes" ON clientes;
|
||||
DROP POLICY IF EXISTS "Clientes podem atualizar seus próprios dados" ON clientes;
|
||||
|
||||
-- Política para permitir inserção de novos clientes (cadastro público)
|
||||
CREATE POLICY "Permitir inserção de novos clientes" ON clientes
|
||||
FOR INSERT WITH CHECK (true);
|
||||
|
||||
-- Política para permitir leitura pública de clientes (necessário para login)
|
||||
CREATE POLICY "Permitir leitura de clientes" ON clientes
|
||||
FOR SELECT USING (true);
|
||||
|
||||
-- Política para permitir que clientes atualizem seus próprios dados
|
||||
CREATE POLICY "Clientes podem atualizar seus próprios dados" ON clientes
|
||||
FOR UPDATE USING (auth.uid()::text = id::text);
|
||||
|
||||
-- Verificar se as políticas foram criadas corretamente
|
||||
SELECT schemaname, tablename, policyname, permissive, roles, cmd, qual
|
||||
FROM pg_policies
|
||||
WHERE tablename = 'clientes';
|
||||
8
sql/add-data-vencimento-vendas.sql
Normal file
8
sql/add-data-vencimento-vendas.sql
Normal file
@@ -0,0 +1,8 @@
|
||||
-- Adicionar coluna data_vencimento na tabela vendas
|
||||
-- Para vendas do tipo "a prazo"
|
||||
|
||||
ALTER TABLE vendas
|
||||
ADD COLUMN IF NOT EXISTS data_vencimento DATE;
|
||||
|
||||
-- Comentário da coluna
|
||||
COMMENT ON COLUMN vendas.data_vencimento IS 'Data de vencimento para vendas a prazo';
|
||||
60
sql/configurar-politicas-catalogo.sql
Normal file
60
sql/configurar-politicas-catalogo.sql
Normal file
@@ -0,0 +1,60 @@
|
||||
-- =============================================
|
||||
-- CONFIGURAR POLÍTICAS DO BUCKET CATALOGO
|
||||
-- Execute este script no SQL Editor do Supabase
|
||||
-- =============================================
|
||||
|
||||
-- Remover políticas antigas se existirem
|
||||
DROP POLICY IF EXISTS "Permitir leitura pública catalogo" ON storage.objects;
|
||||
DROP POLICY IF EXISTS "Permitir upload autenticado catalogo" ON storage.objects;
|
||||
DROP POLICY IF EXISTS "Permitir update autenticado catalogo" ON storage.objects;
|
||||
DROP POLICY IF EXISTS "Permitir delete autenticado catalogo" ON storage.objects;
|
||||
|
||||
-- 1. Leitura pública (qualquer pessoa pode ver as fotos)
|
||||
CREATE POLICY "Permitir leitura pública catalogo"
|
||||
ON storage.objects FOR SELECT
|
||||
USING (bucket_id = 'catalogo');
|
||||
|
||||
-- 2. Upload SEM autenticação (TEMPORÁRIO - para testar)
|
||||
-- Isso permite upload mesmo sem estar logado
|
||||
CREATE POLICY "Permitir upload catalogo"
|
||||
ON storage.objects FOR INSERT
|
||||
WITH CHECK (bucket_id = 'catalogo');
|
||||
|
||||
-- 3. Update SEM autenticação (TEMPORÁRIO - para testar)
|
||||
CREATE POLICY "Permitir update catalogo"
|
||||
ON storage.objects FOR UPDATE
|
||||
USING (bucket_id = 'catalogo');
|
||||
|
||||
-- 4. Delete SEM autenticação (TEMPORÁRIO - para testar)
|
||||
CREATE POLICY "Permitir delete catalogo"
|
||||
ON storage.objects FOR DELETE
|
||||
USING (bucket_id = 'catalogo');
|
||||
|
||||
-- Verificar políticas criadas
|
||||
SELECT
|
||||
'Políticas configuradas:' as status,
|
||||
policyname,
|
||||
cmd
|
||||
FROM pg_policies
|
||||
WHERE tablename = 'objects'
|
||||
AND schemaname = 'storage'
|
||||
AND policyname LIKE '%catalogo%'
|
||||
ORDER BY policyname;
|
||||
|
||||
-- =============================================
|
||||
-- INSTRUÇÕES
|
||||
-- =============================================
|
||||
|
||||
/*
|
||||
✅ Execute este script no SQL Editor do Supabase
|
||||
|
||||
Depois de executar:
|
||||
1. Volte para o sistema
|
||||
2. Acesse Site / Catalogo
|
||||
3. Clique em "Fotos" em um produto
|
||||
4. Tente adicionar uma foto
|
||||
5. Deve funcionar!
|
||||
|
||||
NOTA: Estas políticas são permissivas para facilitar o teste.
|
||||
Depois que funcionar, podemos deixar mais seguro.
|
||||
*/
|
||||
13
sql/create-catalogo-pedidos-table.sql
Normal file
13
sql/create-catalogo-pedidos-table.sql
Normal file
@@ -0,0 +1,13 @@
|
||||
-- Criação da tabela para registrar pedidos gerados pelo catálogo
|
||||
create table if not exists catalogo_pedidos (
|
||||
id uuid primary key default uuid_generate_v4(),
|
||||
created_at timestamp with time zone default timezone('utc', now()),
|
||||
codigo text not null,
|
||||
cliente jsonb not null,
|
||||
itens jsonb not null,
|
||||
total numeric(12,2) not null default 0,
|
||||
mensagem text
|
||||
);
|
||||
|
||||
create index if not exists idx_catalogo_pedidos_created_at on catalogo_pedidos(created_at desc);
|
||||
create index if not exists idx_catalogo_pedidos_codigo on catalogo_pedidos(codigo);
|
||||
56
sql/create-emprestimos-final.sql
Normal file
56
sql/create-emprestimos-final.sql
Normal file
@@ -0,0 +1,56 @@
|
||||
-- =============================================
|
||||
-- CRIAR TABELAS DE EMPRÉSTIMOS - CORREÇÃO FINAL
|
||||
-- =============================================
|
||||
|
||||
-- Criar tabela de empréstimos
|
||||
CREATE TABLE IF NOT EXISTS emprestimos (
|
||||
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
||||
cliente_id UUID REFERENCES clientes(id),
|
||||
data_emprestimo DATE NOT NULL,
|
||||
data_devolucao_prevista DATE NOT NULL,
|
||||
data_devolucao_real DATE,
|
||||
observacoes TEXT,
|
||||
status VARCHAR(20) DEFAULT 'ativo' CHECK (status IN ('ativo', 'devolvido', 'cancelado')),
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Criar tabela de itens de empréstimo
|
||||
CREATE TABLE IF NOT EXISTS emprestimo_itens (
|
||||
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
||||
emprestimo_id UUID REFERENCES emprestimos(id) ON DELETE CASCADE,
|
||||
produto_id UUID REFERENCES produtos(id),
|
||||
produto_variacao_id UUID REFERENCES produto_variacoes(id),
|
||||
quantidade INTEGER NOT NULL,
|
||||
observacoes TEXT,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Criar tabela de configurações (para eliminar erros de configuração)
|
||||
CREATE TABLE IF NOT EXISTS configuracoes (
|
||||
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
||||
chave VARCHAR(255) NOT NULL UNIQUE,
|
||||
valor TEXT,
|
||||
descricao TEXT,
|
||||
tipo VARCHAR(50) DEFAULT 'string',
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Inserir configurações básicas
|
||||
INSERT INTO configuracoes (chave, valor, descricao, tipo) VALUES
|
||||
('evolution_api_url', '', 'URL da API Evolution', 'string'),
|
||||
('whatsapp_alertas_ativo', 'false', 'Ativar alertas WhatsApp', 'boolean')
|
||||
ON CONFLICT (chave) DO NOTHING;
|
||||
|
||||
-- Criar índices para performance
|
||||
CREATE INDEX IF NOT EXISTS idx_emprestimos_cliente ON emprestimos(cliente_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_emprestimos_status ON emprestimos(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_configuracoes_chave ON configuracoes(chave);
|
||||
|
||||
-- Verificar criação
|
||||
SELECT 'Tabelas criadas com sucesso!' as status;
|
||||
SELECT table_name FROM information_schema.tables
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name IN ('emprestimos', 'emprestimo_itens', 'configuracoes')
|
||||
ORDER BY table_name;
|
||||
41
sql/create-venda-parcelas.sql
Normal file
41
sql/create-venda-parcelas.sql
Normal file
@@ -0,0 +1,41 @@
|
||||
-- =====================================================
|
||||
-- TABELA DE PARCELAS INDIVIDUAIS DE VENDAS
|
||||
-- =====================================================
|
||||
|
||||
-- Criar tabela de parcelas
|
||||
CREATE TABLE IF NOT EXISTS venda_parcelas (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
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,
|
||||
status TEXT DEFAULT 'pendente' CHECK (status IN ('pendente', 'pago', 'vencida', 'cancelada')),
|
||||
data_pagamento TIMESTAMP WITH TIME ZONE,
|
||||
pix_payment_id TEXT,
|
||||
pix_qr_code TEXT,
|
||||
pix_qr_code_base64 TEXT,
|
||||
observacoes TEXT,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
UNIQUE(venda_id, numero_parcela)
|
||||
);
|
||||
|
||||
-- Índices
|
||||
CREATE INDEX IF NOT EXISTS idx_venda_parcelas_venda ON venda_parcelas(venda_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_venda_parcelas_status ON venda_parcelas(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_venda_parcelas_vencimento ON venda_parcelas(data_vencimento);
|
||||
|
||||
-- Trigger para updated_at
|
||||
CREATE TRIGGER update_venda_parcelas_updated_at
|
||||
BEFORE UPDATE ON venda_parcelas
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
-- RLS
|
||||
ALTER TABLE venda_parcelas ENABLE ROW LEVEL SECURITY;
|
||||
CREATE POLICY "Enable all operations for authenticated users" ON venda_parcelas FOR ALL USING (true);
|
||||
|
||||
COMMENT ON TABLE venda_parcelas IS 'Armazena as parcelas individuais de cada venda parcelada';
|
||||
COMMENT ON COLUMN venda_parcelas.numero_parcela IS 'Número da parcela (1, 2, 3, etc)';
|
||||
COMMENT ON COLUMN venda_parcelas.status IS 'Status da parcela: pendente, pago, vencida, cancelada';
|
||||
COMMENT ON COLUMN venda_parcelas.pix_payment_id IS 'ID do pagamento PIX do MercadoPago';
|
||||
138
sql/fix-all-missing-tables.sql
Normal file
138
sql/fix-all-missing-tables.sql
Normal file
@@ -0,0 +1,138 @@
|
||||
-- =============================================
|
||||
-- CORRIGIR TODAS AS TABELAS FALTANTES - SOLUÇÃO FINAL
|
||||
-- =============================================
|
||||
|
||||
-- 1. Criar tabela de tipos de despesas
|
||||
CREATE TABLE IF NOT EXISTS tipos_despesa (
|
||||
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
||||
nome VARCHAR(255) 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()
|
||||
);
|
||||
|
||||
-- Inserir tipos de despesas padrão
|
||||
INSERT INTO tipos_despesa (nome, descricao) VALUES
|
||||
('Aluguel', 'Despesas com aluguel do estabelecimento'),
|
||||
('Energia', 'Conta de energia elétrica'),
|
||||
('Água', 'Conta de água'),
|
||||
('Internet', 'Despesas com internet e telefone'),
|
||||
('Marketing', 'Despesas com publicidade e marketing'),
|
||||
('Transporte', 'Despesas com transporte e combustível'),
|
||||
('Material', 'Material de escritório e loja'),
|
||||
('Manutenção', 'Manutenção e reparos'),
|
||||
('Outros', 'Outras despesas diversas')
|
||||
ON CONFLICT (nome) DO NOTHING;
|
||||
|
||||
-- 2. Criar tabela de empréstimos
|
||||
CREATE TABLE IF NOT EXISTS emprestimos (
|
||||
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
||||
cliente_id UUID REFERENCES clientes(id),
|
||||
data_emprestimo DATE NOT NULL,
|
||||
data_devolucao_prevista DATE NOT NULL,
|
||||
data_devolucao_real DATE,
|
||||
observacoes TEXT,
|
||||
status VARCHAR(20) DEFAULT 'ativo' CHECK (status IN ('ativo', 'devolvido', 'cancelado')),
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- 3. Criar tabela de itens de empréstimo
|
||||
CREATE TABLE IF NOT EXISTS emprestimo_itens (
|
||||
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
||||
emprestimo_id UUID REFERENCES emprestimos(id) ON DELETE CASCADE,
|
||||
produto_id UUID REFERENCES produtos(id),
|
||||
produto_variacao_id UUID REFERENCES produto_variacoes(id),
|
||||
quantidade INTEGER NOT NULL,
|
||||
observacoes TEXT,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- 4. Criar tabela de configurações
|
||||
CREATE TABLE IF NOT EXISTS configuracoes (
|
||||
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
||||
chave VARCHAR(255) NOT NULL UNIQUE,
|
||||
valor TEXT,
|
||||
descricao TEXT,
|
||||
tipo VARCHAR(50) DEFAULT 'string',
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Inserir configurações básicas
|
||||
INSERT INTO configuracoes (chave, valor, descricao, tipo) VALUES
|
||||
('evolution_api_url', '', 'URL da API Evolution', 'string'),
|
||||
('evolution_api_key', '', 'Chave da API Evolution', 'string'),
|
||||
('whatsapp_alertas_ativo', 'false', 'Ativar alertas WhatsApp', 'boolean'),
|
||||
('whatsapp_primeiro_alerta_dias', '3', 'Dias antes para primeiro alerta', 'number'),
|
||||
('whatsapp_segundo_alerta_dias', '0', 'Dias antes para segundo alerta', 'number'),
|
||||
('whatsapp_alerta_pos_vencimento_dias', '3', 'Dias após vencimento para alerta', 'number')
|
||||
ON CONFLICT (chave) DO NOTHING;
|
||||
|
||||
-- 5. Verificar se existe a coluna foto_principal na tabela produtos
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'produtos' AND column_name = 'foto_principal') THEN
|
||||
ALTER TABLE produtos ADD COLUMN foto_principal TEXT;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- 6. Verificar se a tabela despesas tem as colunas corretas
|
||||
DO $$
|
||||
BEGIN
|
||||
-- Verificar se existe coluna tipo_id
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'despesas' AND column_name = 'tipo_id') THEN
|
||||
ALTER TABLE despesas ADD COLUMN tipo_id UUID REFERENCES tipos_despesa(id);
|
||||
END IF;
|
||||
|
||||
-- Verificar se existe coluna fornecedor_id
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'despesas' AND column_name = 'fornecedor_id') THEN
|
||||
ALTER TABLE despesas ADD COLUMN fornecedor_id UUID REFERENCES fornecedores(id);
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- 7. Criar índices para melhor performance
|
||||
CREATE INDEX IF NOT EXISTS idx_tipos_despesa_nome ON tipos_despesa(nome);
|
||||
CREATE INDEX IF NOT EXISTS idx_emprestimos_cliente ON emprestimos(cliente_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_emprestimos_status ON emprestimos(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_emprestimos_data ON emprestimos(data_emprestimo);
|
||||
CREATE INDEX IF NOT EXISTS idx_configuracoes_chave ON configuracoes(chave);
|
||||
CREATE INDEX IF NOT EXISTS idx_despesas_tipo ON despesas(tipo_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_despesas_fornecedor ON despesas(fornecedor_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_despesas_data ON despesas(data_despesa);
|
||||
|
||||
-- 8. Verificar criação das tabelas
|
||||
SELECT 'VERIFICAÇÃO DAS TABELAS CRIADAS:' as status;
|
||||
|
||||
SELECT
|
||||
table_name,
|
||||
CASE
|
||||
WHEN table_name IN (
|
||||
SELECT table_name
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = 'public'
|
||||
) THEN '✅ Existe'
|
||||
ELSE '❌ Não existe'
|
||||
END as status
|
||||
FROM (
|
||||
VALUES
|
||||
('tipos_despesa'),
|
||||
('emprestimos'),
|
||||
('emprestimo_itens'),
|
||||
('configuracoes'),
|
||||
('despesas'),
|
||||
('clientes'),
|
||||
('produtos'),
|
||||
('fornecedores')
|
||||
) AS t(table_name)
|
||||
ORDER BY table_name;
|
||||
|
||||
-- 9. Verificar dados inseridos
|
||||
SELECT 'Tipos de despesas cadastrados:' as info, COUNT(*) as total FROM tipos_despesa;
|
||||
SELECT 'Configurações cadastradas:' as info, COUNT(*) as total FROM configuracoes;
|
||||
|
||||
SELECT '🎉 SETUP COMPLETO! Todas as tabelas foram criadas/verificadas.' as resultado;
|
||||
97
sql/fix-missing-tables.sql
Normal file
97
sql/fix-missing-tables.sql
Normal file
@@ -0,0 +1,97 @@
|
||||
-- =============================================
|
||||
-- CORRIGIR TABELAS FALTANTES
|
||||
-- =============================================
|
||||
|
||||
-- Criar tabela de configurações se não existir
|
||||
CREATE TABLE IF NOT EXISTS configuracoes (
|
||||
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
||||
chave VARCHAR(255) NOT NULL UNIQUE,
|
||||
valor TEXT,
|
||||
descricao TEXT,
|
||||
tipo VARCHAR(50) DEFAULT 'string',
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Inserir configurações padrão
|
||||
INSERT INTO configuracoes (chave, valor, descricao, tipo) VALUES
|
||||
('evolution_api_url', '', 'URL da API Evolution', 'string'),
|
||||
('evolution_api_key', '', 'Chave da API Evolution', 'string'),
|
||||
('evolution_instance_name', '', 'Nome da instância Evolution', 'string'),
|
||||
('chatgpt_api_key', '', 'Chave da API ChatGPT', 'string'),
|
||||
('whatsapp_alertas_ativo', 'false', 'Ativar alertas WhatsApp', 'boolean'),
|
||||
('whatsapp_primeiro_alerta_dias', '3', 'Dias antes para primeiro alerta', 'number'),
|
||||
('whatsapp_segundo_alerta_dias', '0', 'Dias antes para segundo alerta', 'number'),
|
||||
('whatsapp_alerta_pos_vencimento_dias', '3', 'Dias após vencimento para alerta', 'number')
|
||||
ON CONFLICT (chave) DO NOTHING;
|
||||
|
||||
-- Verificar se a tabela emprestimos existe, se não criar
|
||||
CREATE TABLE IF NOT EXISTS emprestimos (
|
||||
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
||||
cliente_id UUID REFERENCES clientes(id),
|
||||
data_emprestimo DATE NOT NULL,
|
||||
data_devolucao_prevista DATE NOT NULL,
|
||||
data_devolucao_real DATE,
|
||||
observacoes TEXT,
|
||||
status VARCHAR(20) DEFAULT 'ativo' CHECK (status IN ('ativo', 'devolvido', 'cancelado')),
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Criar tabela de itens de empréstimo se não existir
|
||||
CREATE TABLE IF NOT EXISTS emprestimo_itens (
|
||||
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
||||
emprestimo_id UUID REFERENCES emprestimos(id) ON DELETE CASCADE,
|
||||
produto_id UUID REFERENCES produtos(id),
|
||||
produto_variacao_id UUID REFERENCES produto_variacoes(id),
|
||||
quantidade INTEGER NOT NULL,
|
||||
observacoes TEXT,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Verificar se a tabela devolucoes existe, se não criar
|
||||
CREATE TABLE IF NOT EXISTS devolucoes (
|
||||
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
||||
venda_id UUID REFERENCES vendas(id),
|
||||
tipo VARCHAR(20) DEFAULT 'devolucao' CHECK (tipo IN ('devolucao', 'troca')),
|
||||
motivo TEXT,
|
||||
data_devolucao DATE NOT NULL,
|
||||
valor_devolvido DECIMAL(10,2),
|
||||
observacoes TEXT,
|
||||
status VARCHAR(20) DEFAULT 'processada' CHECK (status IN ('pendente', 'processada', 'cancelada')),
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Criar tabela de itens de devolução se não existir
|
||||
CREATE TABLE IF NOT EXISTS devolucao_itens (
|
||||
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
||||
devolucao_id UUID REFERENCES devolucoes(id) ON DELETE CASCADE,
|
||||
venda_item_id UUID REFERENCES venda_itens(id),
|
||||
quantidade INTEGER NOT NULL,
|
||||
motivo TEXT,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Verificar se existe a coluna foto_principal na tabela produtos
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'produtos' AND column_name = 'foto_principal') THEN
|
||||
ALTER TABLE produtos ADD COLUMN foto_principal TEXT;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- Criar índices para melhor performance
|
||||
CREATE INDEX IF NOT EXISTS idx_configuracoes_chave ON configuracoes(chave);
|
||||
CREATE INDEX IF NOT EXISTS idx_emprestimos_cliente ON emprestimos(cliente_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_emprestimos_status ON emprestimos(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_devolucoes_venda ON devolucoes(venda_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_devolucoes_data ON devolucoes(data_devolucao);
|
||||
|
||||
-- Verificar se as tabelas foram criadas
|
||||
SELECT 'Tabelas verificadas/criadas:' as status;
|
||||
SELECT table_name FROM information_schema.tables
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name IN ('configuracoes', 'emprestimos', 'emprestimo_itens', 'devolucoes', 'devolucao_itens')
|
||||
ORDER BY table_name;
|
||||
49
sql/fix-produtos-constraints.sql
Normal file
49
sql/fix-produtos-constraints.sql
Normal file
@@ -0,0 +1,49 @@
|
||||
-- =============================================
|
||||
-- CORRIGIR CONSTRAINTS DA TABELA PRODUTOS
|
||||
-- =============================================
|
||||
|
||||
-- Verificar constraints existentes
|
||||
SELECT
|
||||
conname as constraint_name,
|
||||
pg_get_constraintdef(oid) as constraint_definition
|
||||
FROM pg_constraint
|
||||
WHERE conrelid = 'produtos'::regclass
|
||||
AND contype = 'c';
|
||||
|
||||
-- Remover constraints problemáticas se existirem
|
||||
DO $$
|
||||
BEGIN
|
||||
-- Remover constraint de gênero se existir
|
||||
IF EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'produtos_genero_check') THEN
|
||||
ALTER TABLE produtos DROP CONSTRAINT produtos_genero_check;
|
||||
END IF;
|
||||
|
||||
-- Remover constraint de estação se existir
|
||||
IF EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'produtos_estacao_check') THEN
|
||||
ALTER TABLE produtos DROP CONSTRAINT produtos_estacao_check;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- Adicionar constraints mais flexíveis
|
||||
ALTER TABLE produtos
|
||||
ADD CONSTRAINT produtos_genero_check
|
||||
CHECK (genero IN ('Menino', 'Menina', 'Unissex', 'Bebê'));
|
||||
|
||||
ALTER TABLE produtos
|
||||
ADD CONSTRAINT produtos_estacao_check
|
||||
CHECK (estacao IN ('Verão', 'Inverno', 'Outono', 'Primavera', 'Ano Todo'));
|
||||
|
||||
-- Verificar se a coluna descrição existe
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'produtos' AND column_name = 'descricao') THEN
|
||||
ALTER TABLE produtos ADD COLUMN descricao TEXT;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- Verificar estrutura final
|
||||
SELECT column_name, data_type, is_nullable
|
||||
FROM information_schema.columns
|
||||
WHERE table_name = 'produtos'
|
||||
ORDER BY ordinal_position;
|
||||
179
sql/setup-bucket-catalogo.sql
Normal file
179
sql/setup-bucket-catalogo.sql
Normal file
@@ -0,0 +1,179 @@
|
||||
-- =============================================
|
||||
-- CONFIGURAR BUCKET 'CATALOGO' PARA FOTOS ADICIONAIS
|
||||
-- Execute este script no SQL Editor do Supabase
|
||||
-- =============================================
|
||||
|
||||
-- 1. CRIAR BUCKET (se não existir)
|
||||
INSERT INTO storage.buckets (id, name, public, file_size_limit, allowed_mime_types)
|
||||
VALUES (
|
||||
'catalogo',
|
||||
'catalogo',
|
||||
true,
|
||||
5242880, -- 5MB
|
||||
ARRAY['image/jpeg', 'image/jpg', 'image/png', 'image/webp', 'image/gif']
|
||||
)
|
||||
ON CONFLICT (id) DO UPDATE
|
||||
SET
|
||||
public = true,
|
||||
file_size_limit = 5242880,
|
||||
allowed_mime_types = ARRAY['image/jpeg', 'image/jpg', 'image/png', 'image/webp', 'image/gif'];
|
||||
|
||||
-- 2. POLÍTICAS DE ACESSO
|
||||
|
||||
-- Remover políticas antigas se existirem
|
||||
DROP POLICY IF EXISTS "Permitir leitura pública catalogo" ON storage.objects;
|
||||
DROP POLICY IF EXISTS "Permitir upload autenticado catalogo" ON storage.objects;
|
||||
DROP POLICY IF EXISTS "Permitir update autenticado catalogo" ON storage.objects;
|
||||
DROP POLICY IF EXISTS "Permitir delete autenticado catalogo" ON storage.objects;
|
||||
|
||||
-- 2.1 Permitir leitura pública
|
||||
CREATE POLICY "Permitir leitura pública catalogo"
|
||||
ON storage.objects FOR SELECT
|
||||
USING (bucket_id = 'catalogo');
|
||||
|
||||
-- 2.2 Permitir upload apenas autenticado
|
||||
CREATE POLICY "Permitir upload autenticado catalogo"
|
||||
ON storage.objects FOR INSERT
|
||||
WITH CHECK (
|
||||
bucket_id = 'catalogo' AND
|
||||
(auth.role() = 'authenticated' OR auth.role() = 'service_role')
|
||||
);
|
||||
|
||||
-- 2.3 Permitir atualização apenas autenticado
|
||||
CREATE POLICY "Permitir update autenticado catalogo"
|
||||
ON storage.objects FOR UPDATE
|
||||
USING (
|
||||
bucket_id = 'catalogo' AND
|
||||
(auth.role() = 'authenticated' OR auth.role() = 'service_role')
|
||||
);
|
||||
|
||||
-- 2.4 Permitir exclusão apenas autenticado
|
||||
CREATE POLICY "Permitir delete autenticado catalogo"
|
||||
ON storage.objects FOR DELETE
|
||||
USING (
|
||||
bucket_id = 'catalogo' AND
|
||||
(auth.role() = 'authenticated' OR auth.role() = 'service_role')
|
||||
);
|
||||
|
||||
-- 3. VERIFICAÇÕES
|
||||
|
||||
-- Verificar se o bucket foi criado
|
||||
SELECT
|
||||
'Bucket criado:' as status,
|
||||
id,
|
||||
name,
|
||||
public,
|
||||
file_size_limit / 1024 / 1024 as "Tamanho máximo (MB)",
|
||||
allowed_mime_types as "Tipos permitidos"
|
||||
FROM storage.buckets
|
||||
WHERE id = 'catalogo';
|
||||
|
||||
-- Verificar políticas
|
||||
SELECT
|
||||
'Políticas configuradas:' as status,
|
||||
policyname,
|
||||
cmd,
|
||||
qual
|
||||
FROM pg_policies
|
||||
WHERE tablename = 'objects'
|
||||
AND schemaname = 'storage'
|
||||
AND policyname LIKE '%catalogo%'
|
||||
ORDER BY policyname;
|
||||
|
||||
-- Contar arquivos existentes (se houver)
|
||||
SELECT
|
||||
'Arquivos no bucket:' as status,
|
||||
COUNT(*) as total,
|
||||
pg_size_pretty(SUM(COALESCE((metadata->>'size')::bigint, 0))) as "Tamanho total"
|
||||
FROM storage.objects
|
||||
WHERE bucket_id = 'catalogo';
|
||||
|
||||
-- =============================================
|
||||
-- ESTRUTURA DE PASTAS RECOMENDADA
|
||||
-- =============================================
|
||||
|
||||
/*
|
||||
catalogo/
|
||||
├── produto_1/
|
||||
│ ├── 1234567890-foto1.jpg
|
||||
│ ├── 1234567891-foto2.jpg
|
||||
│ └── 1234567892-foto3.jpg
|
||||
├── produto_2/
|
||||
│ ├── 1234567893-foto1.jpg
|
||||
│ └── 1234567894-foto2.jpg
|
||||
└── produto_3/
|
||||
└── 1234567895-foto1.jpg
|
||||
|
||||
Organização:
|
||||
- Pasta por produto: produto_{id}
|
||||
- Nome único com timestamp
|
||||
- Acesso público para leitura
|
||||
- Upload/Delete apenas autenticado
|
||||
*/
|
||||
|
||||
-- =============================================
|
||||
-- EXEMPLO DE USO VIA SQL
|
||||
-- =============================================
|
||||
|
||||
-- Listar fotos de um produto específico
|
||||
-- (Substitua 123 pelo ID do produto)
|
||||
/*
|
||||
SELECT
|
||||
name as "Nome do arquivo",
|
||||
created_at as "Data de upload",
|
||||
pg_size_pretty((metadata->>'size')::bigint) as "Tamanho"
|
||||
FROM storage.objects
|
||||
WHERE bucket_id = 'catalogo'
|
||||
AND name LIKE 'produto_123/%'
|
||||
ORDER BY created_at DESC;
|
||||
*/
|
||||
|
||||
-- =============================================
|
||||
-- LIMPEZA (USE COM CUIDADO!)
|
||||
-- =============================================
|
||||
|
||||
-- Para remover todas as fotos de um produto
|
||||
-- ATENÇÃO: Esta operação é irreversível!
|
||||
/*
|
||||
DELETE FROM storage.objects
|
||||
WHERE bucket_id = 'catalogo'
|
||||
AND name LIKE 'produto_123/%';
|
||||
*/
|
||||
|
||||
-- Para remover o bucket completo (CUIDADO!)
|
||||
/*
|
||||
DELETE FROM storage.objects WHERE bucket_id = 'catalogo';
|
||||
DELETE FROM storage.buckets WHERE id = 'catalogo';
|
||||
*/
|
||||
|
||||
-- =============================================
|
||||
-- INSTRUÇÕES FINAIS
|
||||
-- =============================================
|
||||
|
||||
/*
|
||||
✅ BUCKET 'CATALOGO' CONFIGURADO COM SUCESSO!
|
||||
|
||||
Próximos passos:
|
||||
|
||||
1. ✅ Execute este script no SQL Editor do Supabase
|
||||
2. ✅ Verifique as mensagens de verificação acima
|
||||
3. ✅ Acesse o painel admin: Site / Catalogo
|
||||
4. ✅ Clique em "Fotos" em qualquer produto
|
||||
5. ✅ Faça upload de uma foto de teste
|
||||
6. ✅ Verifique no Supabase Storage > catalogo
|
||||
|
||||
O bucket está pronto para uso!
|
||||
|
||||
Características:
|
||||
- 📁 Organização por produto
|
||||
- 🔒 Segurança com RLS
|
||||
- 🌐 Acesso público para leitura
|
||||
- 📸 Suporta: JPEG, PNG, WebP, GIF
|
||||
- 📦 Limite: 5MB por arquivo
|
||||
- 🚀 Integrado com site de catálogo
|
||||
|
||||
Para adicionar fotos via código:
|
||||
- Frontend: Componente SiteCatalogo
|
||||
- Backend: POST /api/produtos/:id/fotos-catalogo
|
||||
- Site: Carrega automaticamente em script.js
|
||||
*/
|
||||
344
sql/supabase-setup.sql
Normal file
344
sql/supabase-setup.sql
Normal file
@@ -0,0 +1,344 @@
|
||||
-- =============================================
|
||||
-- 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';
|
||||
111
sql/supabase-storage.sql
Normal file
111
sql/supabase-storage.sql
Normal file
@@ -0,0 +1,111 @@
|
||||
-- =============================================
|
||||
-- CONFIGURAÇÃO DE STORAGE (BUCKETS) NO SUPABASE
|
||||
-- =============================================
|
||||
|
||||
-- Criar bucket para imagens de produtos
|
||||
INSERT INTO storage.buckets (id, name, public, file_size_limit, allowed_mime_types)
|
||||
VALUES (
|
||||
'produtos',
|
||||
'produtos',
|
||||
true,
|
||||
5242880, -- 5MB
|
||||
ARRAY['image/jpeg', 'image/png', 'image/webp', 'image/gif']
|
||||
) ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- Criar bucket para imagens do catálogo (otimizadas)
|
||||
INSERT INTO storage.buckets (id, name, public, file_size_limit, allowed_mime_types)
|
||||
VALUES (
|
||||
'catalogo',
|
||||
'catalogo',
|
||||
true,
|
||||
3145728, -- 3MB
|
||||
ARRAY['image/jpeg', 'image/png', 'image/webp']
|
||||
) ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- =============================================
|
||||
-- POLÍTICAS DE ACESSO AOS BUCKETS
|
||||
-- =============================================
|
||||
|
||||
-- Política para permitir upload de imagens de produtos (apenas usuários autenticados)
|
||||
CREATE POLICY "Permitir upload de imagens de produtos" ON storage.objects
|
||||
FOR INSERT WITH CHECK (
|
||||
bucket_id = 'produtos' AND
|
||||
auth.role() = 'authenticated'
|
||||
);
|
||||
|
||||
-- Política para permitir leitura pública de imagens de produtos
|
||||
CREATE POLICY "Permitir leitura pública de imagens de produtos" ON storage.objects
|
||||
FOR SELECT USING (bucket_id = 'produtos');
|
||||
|
||||
-- Política para permitir atualização de imagens de produtos
|
||||
CREATE POLICY "Permitir atualização de imagens de produtos" ON storage.objects
|
||||
FOR UPDATE WITH CHECK (
|
||||
bucket_id = 'produtos' AND
|
||||
auth.role() = 'authenticated'
|
||||
);
|
||||
|
||||
-- Política para permitir exclusão de imagens de produtos
|
||||
CREATE POLICY "Permitir exclusão de imagens de produtos" ON storage.objects
|
||||
FOR DELETE USING (
|
||||
bucket_id = 'produtos' AND
|
||||
auth.role() = 'authenticated'
|
||||
);
|
||||
|
||||
-- Política para permitir upload de imagens do catálogo
|
||||
CREATE POLICY "Permitir upload de imagens do catálogo" ON storage.objects
|
||||
FOR INSERT WITH CHECK (
|
||||
bucket_id = 'catalogo' AND
|
||||
auth.role() = 'authenticated'
|
||||
);
|
||||
|
||||
-- Política para permitir leitura pública de imagens do catálogo
|
||||
CREATE POLICY "Permitir leitura pública de imagens do catálogo" ON storage.objects
|
||||
FOR SELECT USING (bucket_id = 'catalogo');
|
||||
|
||||
-- Política para permitir atualização de imagens do catálogo
|
||||
CREATE POLICY "Permitir atualização de imagens do catálogo" ON storage.objects
|
||||
FOR UPDATE WITH CHECK (
|
||||
bucket_id = 'catalogo' AND
|
||||
auth.role() = 'authenticated'
|
||||
);
|
||||
|
||||
-- Política para permitir exclusão de imagens do catálogo
|
||||
CREATE POLICY "Permitir exclusão de imagens do catálogo" ON storage.objects
|
||||
FOR DELETE USING (
|
||||
bucket_id = 'catalogo' AND
|
||||
auth.role() = 'authenticated'
|
||||
);
|
||||
|
||||
-- =============================================
|
||||
-- FUNÇÕES AUXILIARES PARA STORAGE
|
||||
-- =============================================
|
||||
|
||||
-- Função para gerar URL pública de uma imagem
|
||||
CREATE OR REPLACE FUNCTION get_public_url(bucket_name text, file_path text)
|
||||
RETURNS text AS $$
|
||||
BEGIN
|
||||
RETURN 'https://ydhzylfnpqlxnzfcclla.supabase.co/storage/v1/object/public/' || bucket_name || '/' || file_path;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
-- Função para otimizar nome de arquivo
|
||||
CREATE OR REPLACE FUNCTION generate_file_name(original_name text)
|
||||
RETURNS text AS $$
|
||||
DECLARE
|
||||
extension text;
|
||||
clean_name text;
|
||||
timestamp_str text;
|
||||
BEGIN
|
||||
-- Extrair extensão
|
||||
extension := lower(substring(original_name from '\.([^.]*)$'));
|
||||
|
||||
-- Limpar nome (remover caracteres especiais)
|
||||
clean_name := regexp_replace(lower(original_name), '[^a-z0-9.]', '_', 'g');
|
||||
|
||||
-- Gerar timestamp
|
||||
timestamp_str := to_char(now(), 'YYYYMMDD_HH24MISS');
|
||||
|
||||
-- Retornar nome otimizado
|
||||
RETURN timestamp_str || '_' || clean_name;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
Reference in New Issue
Block a user