import mysql from 'mysql2/promise'; import dotenv from 'dotenv'; dotenv.config(); const pool = mysql.createPool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASS, database: process.env.DB_NAME, port: parseInt(process.env.DB_PORT || '3306'), }); // 하드웨어 출시 연도 데이터베이스 (CPU/GPU) const RELEASE_DATES = { // Intel CPU Generations (Mainstream desktop release month/year) 'i9-14': '2023-10', 'i7-14': '2023-10', 'i5-14': '2023-10', 'i9-13': '2022-10', 'i7-13': '2022-10', 'i5-13': '2022-10', 'i9-12': '2021-11', 'i7-12': '2021-11', 'i5-12': '2021-11', 'i9-11': '2021-03', 'i7-11': '2021-03', 'i5-11': '2021-03', 'i9-10': '2020-05', 'i7-10': '2020-05', 'i5-10': '2020-05', 'i9-9': '2018-10', 'i7-9': '2018-10', 'i5-9': '2018-10', 'i7-8': '2017-10', 'i5-8': '2017-10', 'i7-7': '2017-01', 'i5-7': '2017-01', 'i7-6': '2015-08', 'i5-6': '2015-08', 'i7-4': '2013-06', 'i5-4': '2013-06', 'i7-3': '2012-04', 'i5-3': '2012-04', 'i7-2': '2011-01', 'i5-2': '2011-01', // NVIDIA GPU Series 'RTX 4090': '2022-10', 'RTX 4080': '2022-11', 'RTX 4070': '2023-04', 'RTX 4060': '2023-06', 'RTX 3090': '2020-09', 'RTX 3080': '2020-09', 'RTX 3070': '2020-10', 'RTX 3060': '2021-02', 'RTX 2080': '2018-09', 'RTX 2070': '2018-10', 'RTX 2060': '2019-01', 'GTX 1660': '2019-03', 'GTX 1650': '2019-04', 'GTX 1080': '2016-05', 'GTX 1070': '2016-06', 'GTX 1060': '2016-07', 'GTX 1050': '2016-10', 'GTX 980': '2014-09', 'GTX 970': '2014-09', 'GTX 960': '2015-01' }; function inferDateFromSpecs(cpu, gpu) { const cpuStr = (cpu || '').toUpperCase(); const gpuStr = (gpu || '').toUpperCase(); let inferred = null; // 1. GPU 기준 (최신 그래픽카드가 꽂혀있으면 그 시기 이후 구매일 확률이 높음) for (const [key, date] of Object.entries(RELEASE_DATES)) { if (gpuStr.includes(key)) { inferred = date; break; } } // 2. CPU 기준 (GPU에서 못 찾았거나, CPU가 더 최신일 경우) if (!inferred) { for (const [key, date] of Object.entries(RELEASE_DATES)) { // i7-13700 등을 찾기 위해 정규식 또는 포함 여부 확인 if (cpuStr.includes(key)) { inferred = date; break; } } } return inferred ? `${inferred}-01` : null; } async function run() { const connection = await pool.getConnection(); try { const [rows] = await connection.query(` SELECT c.id, c.asset_code, c.purchase_date, s.cpu, s.gpu FROM asset_core c LEFT JOIN asset_spec s ON c.id = s.asset_id `); const updates = []; const unchanged = []; for (const row of rows) { const currentVal = (row.purchase_date || '').trim(); // 구매일자가 없거나 부정확한 경우만 처리 if (!currentVal || currentVal === '-' || currentVal === 'undefined' || currentVal.startsWith('2024-01-01')) { const specDate = inferDateFromSpecs(row.cpu, row.gpu); if (specDate) { updates.push({ id: row.id, date: specDate, code: row.asset_code, cpu: row.cpu, gpu: row.gpu }); } else { unchanged.push({ code: row.asset_code, cpu: row.cpu, gpu: row.gpu }); } } } console.log(`🚀 스펙 분석 결과: ${updates.length}건의 자산 구매일자를 보정합니다.`); for (const item of updates) { await connection.query('UPDATE asset_core SET purchase_date = ? WHERE id = ?', [item.date, item.id]); console.log(`[Update] ${item.code.padEnd(15)} | CPU: ${String(item.cpu).padEnd(20)} | GPU: ${String(item.gpu).padEnd(15)} -> ${item.date}`); } if (unchanged.length > 0) { console.log('\n⚠️ 스펙 정보를 찾을 수 없어 보정하지 못한 자산:'); unchanged.forEach(u => { if (u.code) console.log(`[Skip] ${u.code.padEnd(15)} | CPU: ${u.cpu || '-'} | GPU: ${u.gpu || '-'}`); }); } console.log(`\n✅ 완료: ${updates.length}건 보정됨.`); } catch (err) { console.error('Error:', err); } finally { connection.release(); pool.end(); } } run();