const mysql = require('mysql2/promise'); const path = require('path'); const fs = require('fs'); require('dotenv').config({ path: path.resolve(__dirname, '../.env') }); const dbConfig = { host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, multipleStatements: true }; function outputProgress(data) { console.log(JSON.stringify(data)); } // Explicitly define all metrics-related tables const METRICS_TABLES = [ 'temp_sales_metrics', 'temp_purchase_metrics', 'product_metrics', 'product_time_aggregates', 'vendor_metrics' ]; async function resetMetrics() { outputProgress({ status: 'running', operation: 'Starting metrics reset', percentage: '0' }); const connection = await mysql.createConnection(dbConfig); try { // Disable foreign key checks first await connection.query('SET FOREIGN_KEY_CHECKS = 0'); // Get list of existing metrics tables const [tables] = await connection.query(` SELECT GROUP_CONCAT(table_name) as tables FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name IN (${METRICS_TABLES.map(table => `'${table}'`).join(',')})` ); if (tables[0].tables) { outputProgress({ status: 'running', operation: 'Dropping existing metrics tables', percentage: '20' }); // Drop all existing metrics tables in one query const dropQuery = `DROP TABLE IF EXISTS ${tables[0].tables.split(',').map(table => '`' + table + '`').join(', ')}`; await connection.query(dropQuery); } // Read metrics schema outputProgress({ status: 'running', operation: 'Creating metrics tables', percentage: '40' }); const schemaPath = path.join(__dirname, '../db/metrics-schema.sql'); const schemaSQL = fs.readFileSync(schemaPath, 'utf8'); // Split schema into parts const parts = schemaSQL.split('-- Create optimized indexes'); const tableSchema = parts[0]; // Execute table creation first await connection.query(tableSchema); // Verify all tables were created outputProgress({ status: 'running', operation: 'Verifying tables', percentage: '60' }); const [verifyTables] = await connection.query(` SELECT table_name FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name IN (${METRICS_TABLES.map(table => `'${table}'`).join(',')})` ); const missingTables = METRICS_TABLES.filter(table => !verifyTables.find(t => t.table_name === table) ); if (missingTables.length > 0) { throw new Error(`Failed to create tables: ${missingTables.join(', ')}`); } // Create indexes outputProgress({ status: 'running', operation: 'Creating indexes', percentage: '80' }); // Drop existing indexes if they exist try { await connection.query('DROP INDEX IF EXISTS idx_orders_metrics ON orders'); await connection.query('DROP INDEX IF EXISTS idx_purchase_orders_metrics ON purchase_orders'); } catch (err) { // Ignore any errors dropping indexes console.warn('Warning dropping indexes:', err.message); } // Create new indexes try { await connection.query('CREATE INDEX idx_orders_metrics ON orders (product_id, date, canceled, quantity, price)'); await connection.query('CREATE INDEX idx_purchase_orders_metrics ON purchase_orders (product_id, date, status, ordered, received)'); } catch (err) { // Log index creation errors but don't fail console.warn('Warning creating indexes:', err.message); } // Re-enable foreign key checks await connection.query('SET FOREIGN_KEY_CHECKS = 1'); outputProgress({ status: 'complete', operation: 'Metrics tables have been reset', percentage: '100' }); return { success: true }; } catch (error) { console.error('Error resetting metrics:', error); outputProgress({ status: 'error', operation: 'Failed to reset metrics', error: error.message }); throw error; } finally { await connection.end(); } } // Export the function if being required as a module if (typeof module !== 'undefined' && module.exports) { module.exports = resetMetrics; } // Run directly if called from command line if (require.main === module) { resetMetrics().catch(error => { console.error('Error:', error); process.exit(1); }); }