/** * Local PostgreSQL Database Setup Script * Creates database, tables, and indexes for local development * * Usage: node scripts/setupLocalDB.js */ import { Pool } from 'pg'; import dotenv from 'dotenv'; import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; dotenv.config(); const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); // Default local PostgreSQL connection (can be overridden via env) const localDbConfig = { host: process.env.LOCAL_DB_HOST || '100.121.163.23', port: process.env.LOCAL_DB_PORT || 5432, user: process.env.LOCAL_DB_USER || 'postgres', password: process.env.LOCAL_DB_PASSWORD || 'postgres', database: process.env.LOCAL_DB_NAME || 'institutional_trader' }; /** * Create database if it doesn't exist */ async function createDatabase() { // Connect to postgres database to create our database const adminPool = new Pool({ host: localDbConfig.host, port: localDbConfig.port, user: localDbConfig.user, password: localDbConfig.password, database: 'postgres' // Connect to default postgres database }); try { console.log('šŸ” Checking if database exists...'); const result = await adminPool.query( `SELECT 1 FROM pg_database WHERE datname = $1`, [localDbConfig.database] ); if (result.rows.length === 0) { console.log(`šŸ“¦ Creating database: ${localDbConfig.database}...`); await adminPool.query(`CREATE DATABASE ${localDbConfig.database}`); console.log('āœ… Database created successfully'); } else { console.log('āœ… Database already exists'); } } catch (error) { console.error('āŒ Error creating database:', error.message); throw error; } finally { await adminPool.end(); } } /** * Create all tables */ async function createTables() { const pool = new Pool({ host: localDbConfig.host, port: localDbConfig.port, user: localDbConfig.user, password: localDbConfig.password, database: localDbConfig.database }); try { console.log('šŸ“‹ Creating tables...'); // OptionsFlow_monthly table await pool.query(` CREATE TABLE IF NOT EXISTS "OptionsFlow_monthly" ( "CreatedDate" TEXT, "CreatedTime" TEXT, "Symbol" TEXT, "Type" TEXT, "Volume" TEXT, "Price" TEXT, "Side" TEXT, "CallPut" TEXT, "Strike" TEXT, "Spot" TEXT, "Premium" TEXT, "ExpirationDate" TEXT, "Color" TEXT, "ImpliedVolatility" TEXT, "Dte" TEXT, "ER" TEXT, "StockEtf" TEXT, "Sector" TEXT, "Uoa" TEXT, "Weekly" TEXT, "MktCap" TEXT, "OI" TEXT ); `); console.log(' āœ… OptionsFlow_monthly table created'); // OptionsVolume table await pool.query(` CREATE TABLE IF NOT EXISTS "OptionsVolume" ( "SYMBOL" TEXT, "VOL" NUMERIC, "C VOL" NUMERIC, "P VOL" NUMERIC, "P/C" NUMERIC, "AVG VOL" NUMERIC, "RATIO" NUMERIC, "COI" NUMERIC, "POI" NUMERIC, "DCOI" NUMERIC, "DPOI" NUMERIC ); `); console.log(' āœ… OptionsVolume table created'); // OptionsOpenInterest table await pool.query(` CREATE TABLE IF NOT EXISTS "OptionsOpenInterest" ( "SYMBOL" TEXT, "EXP" TEXT, "C/P" TEXT, "STRIKE" NUMERIC, "OI" NUMERIC, "DOI" NUMERIC ); `); console.log(' āœ… OptionsOpenInterest table created'); // Prices tables (for price context in queries) await pool.query(` CREATE TABLE IF NOT EXISTS prices_intraday_1m ( symbol TEXT, ts TIMESTAMP WITH TIME ZONE, open NUMERIC, high NUMERIC, low NUMERIC, close NUMERIC, volume NUMERIC ); `); console.log(' āœ… prices_intraday_1m table created'); await pool.query(` CREATE TABLE IF NOT EXISTS prices_daily ( symbol TEXT, "Date" DATE, open NUMERIC, high NUMERIC, low NUMERIC, close NUMERIC, volume NUMERIC ); `); console.log(' āœ… prices_daily table created'); // AlertStream_monthly table (for alerts/catalysts) await pool.query(` CREATE TABLE IF NOT EXISTS "AlertStream_monthly" ( "date" TEXT, "timestamp" TEXT, "ticker" TEXT, "type" TEXT, "message" TEXT, "price" NUMERIC, "volume" NUMERIC ); `); console.log(' āœ… AlertStream_monthly table created'); // Create indexes for better query performance console.log('šŸ“Š Creating indexes...'); await pool.query(` CREATE INDEX IF NOT EXISTS idx_optionsflow_symbol ON "OptionsFlow_monthly"("Symbol"); `); await pool.query(` CREATE INDEX IF NOT EXISTS idx_optionsflow_createddate ON "OptionsFlow_monthly"("CreatedDate"); `); await pool.query(` CREATE INDEX IF NOT EXISTS idx_optionsflow_callput ON "OptionsFlow_monthly"("CallPut"); `); await pool.query(` CREATE INDEX IF NOT EXISTS idx_prices_symbol_ts ON prices_intraday_1m(symbol, ts); `); await pool.query(` CREATE INDEX IF NOT EXISTS idx_prices_daily_symbol_date ON prices_daily(symbol, "Date"); `); await pool.query(` CREATE INDEX IF NOT EXISTS idx_alertstream_ticker ON "AlertStream_monthly"("ticker"); `); console.log(' āœ… Indexes created'); console.log('\nāœ… All tables and indexes created successfully!'); } catch (error) { console.error('āŒ Error creating tables:', error.message); throw error; } finally { await pool.end(); } } /** * Test connection */ async function testConnection() { const pool = new Pool({ host: localDbConfig.host, port: localDbConfig.port, user: localDbConfig.user, password: localDbConfig.password, database: localDbConfig.database }); try { const result = await pool.query('SELECT NOW()'); console.log('āœ… Database connection successful'); console.log(` Connected to: ${localDbConfig.database}@${localDbConfig.host}:${localDbConfig.port}`); return true; } catch (error) { console.error('āŒ Database connection failed:', error.message); return false; } finally { await pool.end(); } } /** * Main setup function */ async function main() { console.log('šŸš€ Setting up local PostgreSQL database...\n'); console.log('Configuration:'); console.log(` Host: ${localDbConfig.host}`); console.log(` Port: ${localDbConfig.port}`); console.log(` User: ${localDbConfig.user}`); console.log(` Database: ${localDbConfig.database}\n`); try { // Test connection first console.log('šŸ”Œ Testing connection...'); const adminPool = new Pool({ host: localDbConfig.host, port: localDbConfig.port, user: localDbConfig.user, password: localDbConfig.password, database: 'postgres' }); try { await adminPool.query('SELECT 1'); console.log('āœ… PostgreSQL server is running\n'); } catch (error) { console.error('āŒ Cannot connect to PostgreSQL server'); console.error('\nPlease ensure:'); console.error('1. PostgreSQL is installed and running'); console.error('2. Connection details in .env are correct'); console.error('3. See LOCAL_DB_SETUP.md for installation instructions'); process.exit(1); } finally { await adminPool.end(); } // Create database await createDatabase(); console.log(''); // Create tables await createTables(); console.log(''); // Test final connection await testConnection(); console.log('\nšŸŽ‰ Setup complete! You can now import CSV files.'); } catch (error) { console.error('\nāŒ Setup failed:', error.message); process.exit(1); } } // Run if called directly if (import.meta.url === `file://${process.argv[1]}`) { main(); } export { createDatabase, createTables, testConnection };