chore: sincroniza projeto para gitea

This commit is contained in:
Tiago
2025-11-29 21:31:52 -03:00
parent 33d8645eb4
commit 7e7a0f8867
129 changed files with 24999 additions and 6757 deletions

View 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"
*/

View 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
*/

View 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';

View 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';

View 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.
*/

View 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);

View 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;

View 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';

View 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;

View 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;

View 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;

View 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
View 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
View 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;