import mysql from 'mysql2/promise'; import dotenv from 'dotenv'; dotenv.config(); const { DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT } = process.env; async function migrateSchema() { const connection = await mysql.createConnection({ host: DB_HOST, user: DB_USER, password: DB_PASS, database: DB_NAME, port: parseInt(DB_PORT || '3306') }); console.log('🚀 Phase 1: Creating Normalized Tables & Migrating Data...'); try { await connection.query('SET FOREIGN_KEY_CHECKS = 0'); // --- 1. Drop existing new tables if they exist --- await connection.query('DROP TABLE IF EXISTS asset_core, asset_hardware, asset_location, asset_remote'); // --- 2. Create New Schema --- await connection.query(` CREATE TABLE asset_core ( id VARCHAR(50) PRIMARY KEY, asset_code VARCHAR(100) UNIQUE NOT NULL, category VARCHAR(100), asset_type VARCHAR(100), asset_purpose VARCHAR(255), service_type VARCHAR(50), purchase_corp VARCHAR(100), purchase_date VARCHAR(50), purchase_amount VARCHAR(100), purchase_vendor VARCHAR(255), approval_document VARCHAR(255), memo TEXT, manager_primary VARCHAR(100), manager_secondary VARCHAR(100), current_dept VARCHAR(255), previous_dept VARCHAR(255), user_current VARCHAR(100), previous_user VARCHAR(100), emp_no VARCHAR(20), user_position VARCHAR(50), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; `); await connection.query(` CREATE TABLE asset_hardware ( id INT AUTO_INCREMENT PRIMARY KEY, asset_id VARCHAR(50) NOT NULL, hw_status VARCHAR(50), model_name VARCHAR(255), mainboard VARCHAR(255), os VARCHAR(100), cpu VARCHAR(255), ram VARCHAR(100), gpu VARCHAR(100), storage1 VARCHAR(255), storage2 VARCHAR(255), storage3 VARCHAR(255), monitoring VARCHAR(100), price VARCHAR(100), volume VARCHAR(100), monitor_inch VARCHAR(50), serial_num VARCHAR(100), FOREIGN KEY (asset_id) REFERENCES asset_core(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; `); await connection.query(` CREATE TABLE asset_location ( id INT AUTO_INCREMENT PRIMARY KEY, asset_id VARCHAR(50) NOT NULL, location VARCHAR(255), location_detail VARCHAR(255), location_photo VARCHAR(255), loc_x VARCHAR(20), loc_y VARCHAR(20), is_active BOOLEAN DEFAULT TRUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (asset_id) REFERENCES asset_core(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; `); await connection.query(` CREATE TABLE asset_remote ( id INT AUTO_INCREMENT PRIMARY KEY, asset_id VARCHAR(50) NOT NULL, ip_address VARCHAR(100), mac_address VARCHAR(100), remote_tool VARCHAR(100), remote_id VARCHAR(100), remote_pw VARCHAR(100), is_active BOOLEAN DEFAULT TRUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (asset_id) REFERENCES asset_core(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; `); await connection.query('SET FOREIGN_KEY_CHECKS = 1'); console.log('✅ Normalized tables created.'); // --- 3. Migrate Data from Legacy Tables --- const legacyTables = ['asset_pc', 'asset_server', 'asset_storage', 'asset_remote', 'asset_equipment', 'asset_office_supplies', 'asset_survey', 'asset_vip']; let totalMigrated = 0; for (const table of legacyTables) { try { const [rows] = await connection.query(`SELECT * FROM ${table}`); for (const row of rows) { // 3.1 Insert into asset_core await connection.query(` INSERT IGNORE INTO asset_core ( id, asset_code, category, asset_type, asset_purpose, service_type, purchase_corp, purchase_date, purchase_amount, purchase_vendor, approval_document, memo, manager_primary, manager_secondary, current_dept, previous_dept, user_current, previous_user, emp_no, user_position, created_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) `, [ row.id, row.asset_code, row.category, row.asset_type, row.asset_purpose, row.service_type, row.purchase_corp, row.purchase_date, row.purchase_amount, row.purchase_vendor, row.approval_document, row.memo, row.manager_primary, row.manager_secondary, row.current_dept, row.previous_dept, row.user_current, row.previous_user, row.emp_no, row.user_position, row.created_at ]); // 3.2 Insert into asset_hardware (if hardware fields exist) if (row.model_name || row.cpu || row.ram || row.hw_status) { await connection.query(` INSERT INTO asset_hardware ( asset_id, hw_status, model_name, mainboard, os, cpu, ram, gpu, storage1, storage2, storage3, monitoring, price, volume, monitor_inch, serial_num ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) `, [ row.id, row.hw_status, row.model_name, row.mainboard, row.os, row.cpu, row.ram, row.gpu, row.ssd_1 || row.hdd_1, row.ssd_2 || row.hdd_2, row.hdd_3, row.monitoring, row.price, row.volume, row.monitor_inch, row.serial_num ]); } // 3.3 Insert into asset_location (if location fields exist) if (row.location || row.location_detail) { await connection.query(` INSERT INTO asset_location ( asset_id, location, location_detail, location_photo, loc_x, loc_y ) VALUES (?, ?, ?, ?, ?, ?) `, [ row.id, row.location, row.location_detail, row.location_photo, row.loc_x, row.loc_y ]); } // 3.4 Insert into asset_remote (if network fields exist) // Handle primary network interface if (row.ip_address || row.mac_address || row.remote_tool) { await connection.query(` INSERT INTO asset_remote ( asset_id, ip_address, mac_address, remote_tool, remote_id, remote_pw ) VALUES (?, ?, ?, ?, ?, ?) `, [ row.id, row.ip_address, row.mac_address, row.remote_tool, row.remote_id, row.remote_pw ]); } // Handle secondary network interface (e.g., from server table) if it exists if (row.ip_address_2 || row.remote_tool_2) { await connection.query(` INSERT INTO asset_remote ( asset_id, ip_address, remote_tool, remote_id, remote_pw ) VALUES (?, ?, ?, ?, ?) `, [ row.id, row.ip_address_2, row.remote_tool_2, row.remote_id_2, row.remote_pw_2 ]); } totalMigrated++; } console.log(`- Migrated ${rows.length} records from ${table}`); } catch (err) { console.warn(`- Skipping legacy table ${table}: ${err.message}`); } } console.log(`✅ Phase 1 Data Migration Completed. Total Assets Migrated: ${totalMigrated}`); } catch (err) { console.error('❌ Migration Failed:', err); } finally { await connection.end(); } } migrateSchema();