137 lines
5.8 KiB
JavaScript
137 lines
5.8 KiB
JavaScript
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
|
|
};
|