Primeiro commit
This commit is contained in:
127
scripts/deploy-local.sh
Executable file
127
scripts/deploy-local.sh
Executable file
@@ -0,0 +1,127 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 🚀 Script de Deploy Local - Liberi Kids
|
||||
# Execute: chmod +x scripts/deploy-local.sh && ./scripts/deploy-local.sh
|
||||
|
||||
echo "🚀 Iniciando deploy local do Liberi Kids..."
|
||||
|
||||
# Cores para output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Função para log colorido
|
||||
log() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Verificar se Node.js está instalado
|
||||
if ! command -v node &> /dev/null; then
|
||||
error "Node.js não encontrado. Instale Node.js 18+ primeiro."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verificar versão do Node.js
|
||||
NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
|
||||
if [ "$NODE_VERSION" -lt 18 ]; then
|
||||
error "Node.js versão 18+ é necessária. Versão atual: $(node -v)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "Node.js $(node -v) encontrado ✓"
|
||||
|
||||
# Instalar dependências do servidor
|
||||
log "Instalando dependências do servidor..."
|
||||
npm install
|
||||
if [ $? -ne 0 ]; then
|
||||
error "Falha ao instalar dependências do servidor"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Entrar na pasta do cliente
|
||||
cd client
|
||||
|
||||
# Instalar dependências do cliente
|
||||
log "Instalando dependências do frontend..."
|
||||
npm install
|
||||
if [ $? -ne 0 ]; then
|
||||
error "Falha ao instalar dependências do frontend"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Fazer build do frontend
|
||||
log "Fazendo build do frontend..."
|
||||
npm run build
|
||||
if [ $? -ne 0 ]; then
|
||||
error "Falha no build do frontend"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Voltar para pasta raiz
|
||||
cd ..
|
||||
|
||||
# Verificar se arquivo .env existe
|
||||
if [ ! -f ".env" ]; then
|
||||
warn "Arquivo .env não encontrado. Criando exemplo..."
|
||||
cat > .env << EOF
|
||||
# Configurações do Supabase
|
||||
SUPABASE_URL=https://seu-projeto.supabase.co
|
||||
SUPABASE_ANON_KEY=sua_chave_anonima_aqui
|
||||
|
||||
# Configurações do servidor
|
||||
NODE_ENV=production
|
||||
PORT=5000
|
||||
EOF
|
||||
warn "Configure o arquivo .env com suas credenciais do Supabase!"
|
||||
echo "Edite o arquivo .env antes de continuar."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verificar se PM2 está instalado
|
||||
if ! command -v pm2 &> /dev/null; then
|
||||
log "PM2 não encontrado. Instalando PM2..."
|
||||
npm install -g pm2
|
||||
fi
|
||||
|
||||
# Parar processo anterior se existir
|
||||
pm2 delete liberi-kids 2>/dev/null || true
|
||||
|
||||
# Iniciar aplicação com PM2
|
||||
log "Iniciando aplicação com PM2..."
|
||||
pm2 start server-supabase.js --name "liberi-kids" --env production
|
||||
|
||||
# Configurar PM2 para iniciar automaticamente
|
||||
log "Configurando PM2 para inicialização automática..."
|
||||
pm2 startup
|
||||
pm2 save
|
||||
|
||||
# Status final
|
||||
log "Deploy concluído com sucesso! 🎉"
|
||||
echo ""
|
||||
echo -e "${BLUE}📊 Status da aplicação:${NC}"
|
||||
pm2 status
|
||||
|
||||
echo ""
|
||||
echo -e "${BLUE}🌐 Acesso:${NC}"
|
||||
echo " Local: http://localhost:5000"
|
||||
echo " Rede: http://$(hostname -I | awk '{print $1}'):5000"
|
||||
|
||||
echo ""
|
||||
echo -e "${BLUE}📋 Comandos úteis:${NC}"
|
||||
echo " Ver logs: pm2 logs liberi-kids"
|
||||
echo " Reiniciar: pm2 restart liberi-kids"
|
||||
echo " Parar: pm2 stop liberi-kids"
|
||||
echo " Status: pm2 status"
|
||||
|
||||
echo ""
|
||||
log "Aplicação rodando em produção! ✓"
|
||||
126
scripts/deploy-vercel.sh
Executable file
126
scripts/deploy-vercel.sh
Executable file
@@ -0,0 +1,126 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 🚀 Script de Deploy Vercel - Liberi Kids
|
||||
# Execute: chmod +x scripts/deploy-vercel.sh && ./scripts/deploy-vercel.sh
|
||||
|
||||
echo "☁️ Iniciando deploy no Vercel..."
|
||||
|
||||
# Cores para output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
log() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Verificar se Vercel CLI está instalado
|
||||
if ! command -v vercel &> /dev/null; then
|
||||
log "Instalando Vercel CLI..."
|
||||
npm install -g vercel
|
||||
fi
|
||||
|
||||
# Criar arquivo vercel.json se não existir
|
||||
if [ ! -f "vercel.json" ]; then
|
||||
log "Criando configuração do Vercel..."
|
||||
cat > vercel.json << 'EOF'
|
||||
{
|
||||
"version": 2,
|
||||
"name": "liberi-kids-estoque",
|
||||
"builds": [
|
||||
{
|
||||
"src": "server-supabase.js",
|
||||
"use": "@vercel/node"
|
||||
},
|
||||
{
|
||||
"src": "client/package.json",
|
||||
"use": "@vercel/static-build",
|
||||
"config": {
|
||||
"distDir": "build"
|
||||
}
|
||||
}
|
||||
],
|
||||
"routes": [
|
||||
{
|
||||
"src": "/api/(.*)",
|
||||
"dest": "/server-supabase.js"
|
||||
},
|
||||
{
|
||||
"src": "/(.*)",
|
||||
"dest": "/client/build/$1"
|
||||
}
|
||||
],
|
||||
"env": {
|
||||
"NODE_ENV": "production"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Criar arquivo .vercelignore se não existir
|
||||
if [ ! -f ".vercelignore" ]; then
|
||||
log "Criando .vercelignore..."
|
||||
cat > .vercelignore << 'EOF'
|
||||
node_modules
|
||||
.env
|
||||
.env.local
|
||||
.env.development
|
||||
.env.test
|
||||
.env.production
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.DS_Store
|
||||
.vscode
|
||||
.idea
|
||||
*.log
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Verificar se as dependências estão instaladas
|
||||
log "Verificando dependências..."
|
||||
npm install
|
||||
|
||||
cd client
|
||||
npm install
|
||||
cd ..
|
||||
|
||||
# Fazer login no Vercel (se necessário)
|
||||
log "Verificando login no Vercel..."
|
||||
vercel whoami || {
|
||||
log "Faça login no Vercel:"
|
||||
vercel login
|
||||
}
|
||||
|
||||
# Deploy
|
||||
log "Fazendo deploy no Vercel..."
|
||||
vercel --prod
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
log "Deploy concluído com sucesso! 🎉"
|
||||
echo ""
|
||||
echo -e "${BLUE}📋 Próximos passos:${NC}"
|
||||
echo "1. Configure as variáveis de ambiente no dashboard do Vercel:"
|
||||
echo " - SUPABASE_URL"
|
||||
echo " - SUPABASE_ANON_KEY"
|
||||
echo ""
|
||||
echo "2. Acesse: https://vercel.com/dashboard"
|
||||
echo "3. Selecione seu projeto"
|
||||
echo "4. Vá em Settings > Environment Variables"
|
||||
echo "5. Adicione suas variáveis do Supabase"
|
||||
echo ""
|
||||
echo -e "${GREEN}✓ Aplicação disponível na URL fornecida pelo Vercel${NC}"
|
||||
else
|
||||
error "Falha no deploy. Verifique os logs acima."
|
||||
exit 1
|
||||
fi
|
||||
84
scripts/fix-devolucoes.js
Executable file
84
scripts/fix-devolucoes.js
Executable file
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fetch = require('node-fetch');
|
||||
|
||||
async function limparDevolucoesDuplicadas() {
|
||||
try {
|
||||
console.log('🔧 Iniciando limpeza de devoluções duplicadas...');
|
||||
|
||||
const response = await fetch('http://localhost:5000/api/devolucoes/limpar-duplicadas', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
console.log(`✅ ${result.message}`);
|
||||
console.log(`📊 Total removidas: ${result.removidas}`);
|
||||
} else {
|
||||
console.log('❌ Erro:', result.error);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Erro ao limpar devoluções:', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
async function verificarEstadoDevolucoes() {
|
||||
try {
|
||||
console.log('\n📋 Verificando estado atual das devoluções...');
|
||||
|
||||
const response = await fetch('http://localhost:5000/api/devolucoes');
|
||||
const devolucoes = await response.json();
|
||||
|
||||
console.log(`📊 Total de devoluções: ${devolucoes.length}`);
|
||||
|
||||
// Agrupar por venda para verificar duplicatas
|
||||
const porVenda = {};
|
||||
devolucoes.forEach(dev => {
|
||||
const key = dev.venda_id;
|
||||
if (!porVenda[key]) {
|
||||
porVenda[key] = [];
|
||||
}
|
||||
porVenda[key].push(dev);
|
||||
});
|
||||
|
||||
console.log(`📊 Vendas com devoluções: ${Object.keys(porVenda).length}`);
|
||||
|
||||
// Verificar vendas com múltiplas devoluções
|
||||
const vendasComMultiplas = Object.entries(porVenda)
|
||||
.filter(([_, devs]) => devs.length > 1);
|
||||
|
||||
if (vendasComMultiplas.length > 0) {
|
||||
console.log(`⚠️ Vendas com múltiplas devoluções: ${vendasComMultiplas.length}`);
|
||||
vendasComMultiplas.forEach(([vendaId, devs]) => {
|
||||
console.log(` - Venda ${vendaId}: ${devs.length} devoluções`);
|
||||
});
|
||||
} else {
|
||||
console.log('✅ Nenhuma venda com múltiplas devoluções encontrada');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Erro ao verificar devoluções:', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log('🔧 Sistema de Correção de Devoluções/Trocas - Liberi Kids');
|
||||
console.log('======================================================');
|
||||
|
||||
await verificarEstadoDevolucoes();
|
||||
await limparDevolucoesDuplicadas();
|
||||
await verificarEstadoDevolucoes();
|
||||
|
||||
console.log('\n✅ Processo concluído!');
|
||||
console.log('\n📋 Próximos passos:');
|
||||
console.log('1. Teste uma devolução simples');
|
||||
console.log('2. Teste uma troca de produto');
|
||||
console.log('3. Verifique se o estoque está sendo atualizado corretamente');
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
58
scripts/fix-google-drive.sh
Executable file
58
scripts/fix-google-drive.sh
Executable file
@@ -0,0 +1,58 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "🔧 Script de Correção Google Drive - Liberi Kids"
|
||||
echo "=============================================="
|
||||
echo ""
|
||||
|
||||
echo "📋 Checklist de Configuração:"
|
||||
echo ""
|
||||
echo "1. ✅ Verificar se Google Drive API está ativa"
|
||||
echo " - Acesse: https://console.cloud.google.com/apis/library/drive.googleapis.com"
|
||||
echo " - Clique em 'Ativar' se não estiver ativo"
|
||||
echo ""
|
||||
|
||||
echo "2. ✅ Configurar Tela de Consentimento OAuth"
|
||||
echo " - Acesse: https://console.cloud.google.com/apis/credentials/consent"
|
||||
echo " - Tipo: Externo"
|
||||
echo " - Nome do app: Liberi Kids - Sistema de Estoque"
|
||||
echo " - Adicionar escopos: drive.file e drive.readonly"
|
||||
echo ""
|
||||
|
||||
echo "3. 🎯 CRÍTICO: Adicionar Usuários de Teste"
|
||||
echo " - Na tela de consentimento, seção 'Usuários de teste'"
|
||||
echo " - Adicionar SEU EMAIL (o mesmo que vai usar para autorizar)"
|
||||
echo " - Sem isso, você receberá erro de autorização"
|
||||
echo ""
|
||||
|
||||
echo "4. ✅ Verificar Credenciais OAuth"
|
||||
echo " - Acesse: https://console.cloud.google.com/apis/credentials"
|
||||
echo " - URIs de redirecionamento: http://localhost:5000/auth/google-drive/callback"
|
||||
echo ""
|
||||
|
||||
echo "5. 🔄 Testar Configuração"
|
||||
echo " - Recarregar página de Configurações"
|
||||
echo " - Tentar autorizar novamente"
|
||||
echo " - Usar o email que foi adicionado como usuário de teste"
|
||||
echo ""
|
||||
|
||||
echo "📞 URLs Importantes:"
|
||||
echo " - Google Cloud Console: https://console.cloud.google.com/"
|
||||
echo " - APIs & Services: https://console.cloud.google.com/apis/"
|
||||
echo " - OAuth Consent: https://console.cloud.google.com/apis/credentials/consent"
|
||||
echo " - Credentials: https://console.cloud.google.com/apis/credentials"
|
||||
echo ""
|
||||
|
||||
echo "🚨 Lembre-se: Use o MESMO EMAIL em 'Usuários de teste' e na autorização!"
|
||||
echo ""
|
||||
|
||||
# Verificar se o servidor está rodando
|
||||
if curl -s http://localhost:5000/api/google-drive/status > /dev/null; then
|
||||
echo "✅ Servidor está rodando"
|
||||
echo "🔗 Acesse: http://localhost:3000/configuracoes"
|
||||
else
|
||||
echo "❌ Servidor não está rodando"
|
||||
echo "Execute: npm start"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Após configurar no Google Cloud Console, recarregue a página e tente novamente!"
|
||||
99
scripts/init-supabase.js
Normal file
99
scripts/init-supabase.js
Normal file
@@ -0,0 +1,99 @@
|
||||
const supabase = require('../config/supabase');
|
||||
|
||||
async function initializeSupabaseTables() {
|
||||
console.log('🚀 Inicializando tabelas no Supabase...');
|
||||
|
||||
try {
|
||||
// 1. Criar tabela de fornecedores
|
||||
console.log('📦 Criando tabela fornecedores...');
|
||||
const { error: fornecedoresError } = await supabase.rpc('create_fornecedores_table');
|
||||
if (fornecedoresError && !fornecedoresError.message.includes('already exists')) {
|
||||
console.error('Erro ao criar tabela fornecedores:', fornecedoresError);
|
||||
} else {
|
||||
console.log('✅ Tabela fornecedores criada/verificada');
|
||||
}
|
||||
|
||||
// 2. Criar tabela de produtos
|
||||
console.log('📦 Criando tabela produtos...');
|
||||
const { error: produtosError } = await supabase.rpc('create_produtos_table');
|
||||
if (produtosError && !produtosError.message.includes('already exists')) {
|
||||
console.error('Erro ao criar tabela produtos:', produtosError);
|
||||
} else {
|
||||
console.log('✅ Tabela produtos criada/verificada');
|
||||
}
|
||||
|
||||
// 3. Criar tabela de variações de produtos
|
||||
console.log('📦 Criando tabela produto_variacoes...');
|
||||
const { error: variacoesError } = await supabase.rpc('create_produto_variacoes_table');
|
||||
if (variacoesError && !variacoesError.message.includes('already exists')) {
|
||||
console.error('Erro ao criar tabela produto_variacoes:', variacoesError);
|
||||
} else {
|
||||
console.log('✅ Tabela produto_variacoes criada/verificada');
|
||||
}
|
||||
|
||||
// 4. Criar tabela de clientes
|
||||
console.log('📦 Criando tabela clientes...');
|
||||
const { error: clientesError } = await supabase.rpc('create_clientes_table');
|
||||
if (clientesError && !clientesError.message.includes('already exists')) {
|
||||
console.error('Erro ao criar tabela clientes:', clientesError);
|
||||
} else {
|
||||
console.log('✅ Tabela clientes criada/verificada');
|
||||
}
|
||||
|
||||
// 5. Criar tabela de tipos de despesas
|
||||
console.log('📦 Criando tabela tipos_despesas...');
|
||||
const { error: tiposDespesasError } = await supabase.rpc('create_tipos_despesas_table');
|
||||
if (tiposDespesasError && !tiposDespesasError.message.includes('already exists')) {
|
||||
console.error('Erro ao criar tabela tipos_despesas:', tiposDespesasError);
|
||||
} else {
|
||||
console.log('✅ Tabela tipos_despesas criada/verificada');
|
||||
}
|
||||
|
||||
// 6. Criar tabela de despesas
|
||||
console.log('📦 Criando tabela despesas...');
|
||||
const { error: despesasError } = await supabase.rpc('create_despesas_table');
|
||||
if (despesasError && !despesasError.message.includes('already exists')) {
|
||||
console.error('Erro ao criar tabela despesas:', despesasError);
|
||||
} else {
|
||||
console.log('✅ Tabela despesas criada/verificada');
|
||||
}
|
||||
|
||||
// 7. Criar tabela de vendas
|
||||
console.log('📦 Criando tabela vendas...');
|
||||
const { error: vendasError } = await supabase.rpc('create_vendas_table');
|
||||
if (vendasError && !vendasError.message.includes('already exists')) {
|
||||
console.error('Erro ao criar tabela vendas:', vendasError);
|
||||
} else {
|
||||
console.log('✅ Tabela vendas criada/verificada');
|
||||
}
|
||||
|
||||
// 8. Criar tabela de itens de venda
|
||||
console.log('📦 Criando tabela venda_itens...');
|
||||
const { error: vendaItensError } = await supabase.rpc('create_venda_itens_table');
|
||||
if (vendaItensError && !vendaItensError.message.includes('already exists')) {
|
||||
console.error('Erro ao criar tabela venda_itens:', vendaItensError);
|
||||
} else {
|
||||
console.log('✅ Tabela venda_itens criada/verificada');
|
||||
}
|
||||
|
||||
console.log('🎉 Inicialização do Supabase concluída!');
|
||||
|
||||
// Testar conexão
|
||||
const { data, error } = await supabase.from('fornecedores').select('count', { count: 'exact' });
|
||||
if (error) {
|
||||
console.error('❌ Erro ao testar conexão:', error);
|
||||
} else {
|
||||
console.log('✅ Conexão com Supabase funcionando!');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Erro geral na inicialização:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// Executar se chamado diretamente
|
||||
if (require.main === module) {
|
||||
initializeSupabaseTables();
|
||||
}
|
||||
|
||||
module.exports = initializeSupabaseTables;
|
||||
72
scripts/migrate-despesas-text-fields.js
Normal file
72
scripts/migrate-despesas-text-fields.js
Normal file
@@ -0,0 +1,72 @@
|
||||
const supabase = require('../config/supabase');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
async function migrateDespesasToTextFields() {
|
||||
console.log('🔄 Migrando tabela despesas para campos de texto livre...');
|
||||
|
||||
try {
|
||||
// Ler o script SQL
|
||||
const sqlScript = fs.readFileSync(
|
||||
path.join(__dirname, '../sql/alter-despesas-text-fields.sql'),
|
||||
'utf8'
|
||||
);
|
||||
|
||||
// Dividir o script em comandos individuais
|
||||
const commands = sqlScript
|
||||
.split(';')
|
||||
.map(cmd => cmd.trim())
|
||||
.filter(cmd => cmd.length > 0 && !cmd.startsWith('--'));
|
||||
|
||||
console.log(`📝 Executando ${commands.length} comandos SQL...`);
|
||||
|
||||
// Executar cada comando
|
||||
for (let i = 0; i < commands.length; i++) {
|
||||
const command = commands[i];
|
||||
console.log(`⚡ Executando comando ${i + 1}/${commands.length}...`);
|
||||
|
||||
try {
|
||||
const { error } = await supabase.rpc('exec_sql', { sql_query: command });
|
||||
if (error) {
|
||||
console.log(`⚠️ Comando ${i + 1} com aviso:`, error.message);
|
||||
} else {
|
||||
console.log(`✅ Comando ${i + 1} executado com sucesso`);
|
||||
}
|
||||
} catch (cmdError) {
|
||||
console.log(`⚠️ Erro no comando ${i + 1}:`, cmdError.message);
|
||||
}
|
||||
}
|
||||
|
||||
// Verificar se as colunas foram criadas
|
||||
console.log('🔍 Verificando estrutura da tabela...');
|
||||
const { data: columns, error: columnsError } = await supabase
|
||||
.from('information_schema.columns')
|
||||
.select('column_name')
|
||||
.eq('table_name', 'despesas')
|
||||
.in('column_name', ['tipo_nome', 'fornecedor_nome']);
|
||||
|
||||
if (columnsError) {
|
||||
console.log('⚠️ Não foi possível verificar as colunas:', columnsError.message);
|
||||
} else {
|
||||
const columnNames = columns.map(col => col.column_name);
|
||||
if (columnNames.includes('tipo_nome') && columnNames.includes('fornecedor_nome')) {
|
||||
console.log('✅ Colunas tipo_nome e fornecedor_nome criadas com sucesso!');
|
||||
} else {
|
||||
console.log('⚠️ Algumas colunas podem não ter sido criadas:', columnNames);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('🎉 Migração concluída!');
|
||||
console.log('📋 Agora você pode usar campos de texto livre para Tipo de Despesa e Fornecedor');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Erro durante a migração:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// Executar se chamado diretamente
|
||||
if (require.main === module) {
|
||||
migrateDespesasToTextFields();
|
||||
}
|
||||
|
||||
module.exports = migrateDespesasToTextFields;
|
||||
60
scripts/migrate-pix-fields.js
Normal file
60
scripts/migrate-pix-fields.js
Normal file
@@ -0,0 +1,60 @@
|
||||
const { createClient } = require('@supabase/supabase-js');
|
||||
require('dotenv').config();
|
||||
|
||||
const supabase = createClient(
|
||||
process.env.SUPABASE_URL,
|
||||
process.env.SUPABASE_ANON_KEY
|
||||
);
|
||||
|
||||
async function migratePIXFields() {
|
||||
console.log('🏦 Iniciando migração dos campos PIX...');
|
||||
|
||||
try {
|
||||
// Executar as alterações na tabela vendas
|
||||
const queries = [
|
||||
"ALTER TABLE vendas ADD COLUMN IF NOT EXISTS status_pagamento VARCHAR(20) DEFAULT 'pendente'",
|
||||
"ALTER TABLE vendas ADD COLUMN IF NOT EXISTS data_pagamento TIMESTAMP",
|
||||
"ALTER TABLE vendas ADD COLUMN IF NOT EXISTS pix_payment_id VARCHAR(100)",
|
||||
"ALTER TABLE vendas ADD COLUMN IF NOT EXISTS pix_qr_code TEXT",
|
||||
"ALTER TABLE vendas ADD COLUMN IF NOT EXISTS metodo_pagamento VARCHAR(20) DEFAULT 'dinheiro'"
|
||||
];
|
||||
|
||||
for (const query of queries) {
|
||||
console.log(`Executando: ${query}`);
|
||||
const { error } = await supabase.rpc('exec_sql', { sql: query });
|
||||
|
||||
if (error) {
|
||||
console.error(`Erro ao executar query: ${error.message}`);
|
||||
// Continuar mesmo com erro (campo pode já existir)
|
||||
} else {
|
||||
console.log('✅ Query executada com sucesso');
|
||||
}
|
||||
}
|
||||
|
||||
// Criar índices
|
||||
const indexes = [
|
||||
"CREATE INDEX IF NOT EXISTS idx_vendas_status_pagamento ON vendas(status_pagamento)",
|
||||
"CREATE INDEX IF NOT EXISTS idx_vendas_pix_payment_id ON vendas(pix_payment_id)"
|
||||
];
|
||||
|
||||
for (const index of indexes) {
|
||||
console.log(`Criando índice: ${index}`);
|
||||
const { error } = await supabase.rpc('exec_sql', { sql: index });
|
||||
|
||||
if (error) {
|
||||
console.error(`Erro ao criar índice: ${error.message}`);
|
||||
} else {
|
||||
console.log('✅ Índice criado com sucesso');
|
||||
}
|
||||
}
|
||||
|
||||
console.log('🎉 Migração PIX concluída com sucesso!');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Erro na migração:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Executar migração
|
||||
migratePIXFields();
|
||||
Reference in New Issue
Block a user