const { Pool } = require('pg'); const { DATABASE_URL } = require('./config'); const pool = new Pool({ connectionString: DATABASE_URL }); const initDB = async () => { try { await pool.query(`SET TIME ZONE 'America/Sao_Paulo';`); await pool.query(` CREATE TABLE IF NOT EXISTS orders ( id SERIAL PRIMARY KEY, cliente_nome VARCHAR(255), data_pedido VARCHAR(50), data_pedido_date DATE, valor_pedido NUMERIC(10, 2), produto_id VARCHAR(100), produto_descricao TEXT, quantidade INTEGER, valor_unitario NUMERIC(10, 5), created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP ); `); await pool.query(`ALTER TABLE orders ADD COLUMN IF NOT EXISTS pedido_id VARCHAR(100);`).catch(() => {}); await pool.query(`ALTER TABLE orders ADD COLUMN IF NOT EXISTS cliente_fone VARCHAR(50);`).catch(() => {}); await pool.query(`ALTER TABLE orders ADD COLUMN IF NOT EXISTS data_pedido_date DATE;`).catch(() => {}); await pool.query(` ALTER TABLE orders ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'America/Sao_Paulo', ALTER COLUMN created_at SET DEFAULT CURRENT_TIMESTAMP; `).catch(() => {}); await pool.query(` UPDATE orders SET data_pedido_date = CASE WHEN data_pedido ~ '^\\d{4}[-/]\\d{1,2}[-/]\\d{1,2}' THEN to_date(replace(left(data_pedido, 10), '/', '-'), 'YYYY-MM-DD') WHEN data_pedido ~ '^\\d{1,2}[-/]\\d{1,2}[-/]\\d{4}' THEN to_date(replace(left(data_pedido, 10), '/', '-'), 'DD-MM-YYYY') ELSE NULL END WHERE data_pedido_date IS NULL AND data_pedido IS NOT NULL AND data_pedido != ''; `).catch(err => { console.error('Notice: Could not backfill normalized order dates:', err.message); }); await pool.query(`CREATE UNIQUE INDEX IF NOT EXISTS unique_order_product ON orders (pedido_id, produto_id);`).catch(err => { console.error('Notice: Could not create unique index (might already exist or there are duplicates):', err.message); }); await pool.query(` CREATE TABLE IF NOT EXISTS stock ( produto_id VARCHAR(100) PRIMARY KEY, nome TEXT, saldo INTEGER DEFAULT 0, delta_estoque INTEGER DEFAULT 0, updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP ); `); await pool.query(` ALTER TABLE stock ALTER COLUMN updated_at TYPE TIMESTAMPTZ USING updated_at AT TIME ZONE 'America/Sao_Paulo', ALTER COLUMN updated_at SET DEFAULT CURRENT_TIMESTAMP; `).catch(() => {}); await pool.query(` CREATE TABLE IF NOT EXISTS stock_campaign_queue ( id SERIAL PRIMARY KEY, base_product_name TEXT NOT NULL, produto_id VARCHAR(100) NOT NULL, nome TEXT NOT NULL, saldo INTEGER DEFAULT 0, delta_estoque INTEGER DEFAULT 0, status VARCHAR(20) DEFAULT 'pending', attempts INTEGER DEFAULT 0, last_error TEXT, created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, sent_at TIMESTAMPTZ ); `); await pool.query(` ALTER TABLE stock_campaign_queue ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'America/Sao_Paulo', ALTER COLUMN created_at SET DEFAULT CURRENT_TIMESTAMP, ALTER COLUMN updated_at TYPE TIMESTAMPTZ USING updated_at AT TIME ZONE 'America/Sao_Paulo', ALTER COLUMN updated_at SET DEFAULT CURRENT_TIMESTAMP, ALTER COLUMN sent_at TYPE TIMESTAMPTZ USING sent_at AT TIME ZONE 'America/Sao_Paulo'; `).catch(() => {}); await pool.query(` UPDATE stock_campaign_queue SET base_product_name = TRIM(regexp_replace( base_product_name, '\\s+-\\s+(?:(?:PP|P|M|G|GG|XG|XGG|EG|EGG|EXG|U|UNICO|ÚNICO|\\d{2})(?:/(?:PP|P|M|G|GG|XG|XGG|EG|EGG|EXG|U|UNICO|ÚNICO|\\d{2}))*)$', '', 'i' )) WHERE status IN ('pending', 'failed', 'processing') AND base_product_name ~* '\\s+-\\s+(?:(?:PP|P|M|G|GG|XG|XGG|EG|EGG|EXG|U|UNICO|ÚNICO|\\d{2})(?:/(?:PP|P|M|G|GG|XG|XGG|EG|EGG|EXG|U|UNICO|ÚNICO|\\d{2}))*)$'; `).catch(err => { console.error('Notice: Could not normalize queued campaign product names:', err.message); }); await pool.query(` UPDATE stock_campaign_queue SET base_product_name = nome WHERE status IN ('pending', 'failed', 'processing') AND nome ILIKE 'ETIQUETA%' AND base_product_name != nome; `).catch(err => { console.error('Notice: Could not restore queued etiqueta product names:', err.message); }); await pool.query(`CREATE INDEX IF NOT EXISTS idx_stock_campaign_queue_status ON stock_campaign_queue (status);`); await pool.query(`CREATE INDEX IF NOT EXISTS idx_orders_cliente_fone ON orders (cliente_fone);`); await pool.query(`CREATE INDEX IF NOT EXISTS idx_orders_produto_id ON orders (produto_id);`); await pool.query(`CREATE INDEX IF NOT EXISTS idx_orders_data_pedido_date ON orders (data_pedido_date);`); console.log('Database initialized successfully.'); } catch (err) { console.error('Failed to initialize database:', err); throw err; } }; module.exports = { pool, initDB };