const XLSX = require('xlsx'); const mysql = require('mysql2/promise'); const dotenv = require('dotenv'); const path = require('path'); dotenv.config({ path: path.join(__dirname, '../.env') }); const { DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT } = process.env; async function extractFailures() { const connection = await mysql.createConnection({ host: DB_HOST, user: DB_USER, password: DB_PASS, database: DB_NAME, port: parseInt(DB_PORT || '3306') }); console.log('πŸ” μ‹€νŒ¨ 데이터 μΆ”μΆœ 쀑...'); const workbook = XLSX.readFile('asset_pc (2026.06.15).xlsx'); const sheet = workbook.Sheets[workbook.SheetNames[0]]; const rawData = XLSX.utils.sheet_to_json(sheet); // ν˜„μž¬ DB에 μ‘΄μž¬ν•˜λŠ” λͺ¨λ“  asset_core ID 쑰회 const [existingRows] = await connection.query('SELECT id FROM asset_core'); const existingIds = new Set(existingRows.map(r => r.id)); const failures = []; for (let i = 0; i < rawData.length; i++) { const row = rawData[i]; const assetId = `PC_20260615_${String(i + 1).padStart(4, '0')}`; // DB에 ν•΄λ‹Ή IDκ°€ μ—†λŠ” 경우 = μ‹€νŒ¨(좩돌 λ“±μ˜ 이유둜 μž…λ ₯λ˜μ§€ μ•ŠμŒ) λ˜λŠ” μŠ€ν‚΅λœ 데이터 // ν•˜μ§€λ§Œ 이전 λ‘œκ·Έμ—μ„œ 'Duplicate entry'둜 μ—λŸ¬κ°€ λ‚¬λ˜ ν•­λͺ©λ“€μ„ μ°ΎλŠ” 것이 λͺ©μ  // λ‘œμ§μƒ ID 생성 κ·œμΉ™μ— 따라 ν•΄λ‹Ή IDκ°€ DB에 μ—†μœΌλ©΄ μž…λ ₯에 μ‹€νŒ¨ν•œ ν–‰μž„ if (!existingIds.has(assetId)) { failures.push({ excel_row: i + 2, generated_id: assetId, ...row }); } } if (failures.length > 0) { const newWb = XLSX.utils.book_new(); const newWs = XLSX.utils.json_to_sheet(failures); XLSX.utils.book_append_sheet(newWb, newWs, 'Failures'); const fileName = 'asset_pc_failures_20260615.xlsx'; XLSX.writeFile(newWb, fileName); console.log(`βœ… μΆ”μΆœ μ™„λ£Œ: ${failures.length}건의 μ‹€νŒ¨ 데이터λ₯Ό ${fileName}에 μ €μž₯ν–ˆμŠ΅λ‹ˆλ‹€.`); } else { console.log('μž…λ ₯λ˜μ§€ μ•Šμ€ 데이터가 μ—†μŠ΅λ‹ˆλ‹€.'); } await connection.end(); } extractFailures().catch(console.error);